4Gewinnt: Spielsteine setzen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • 4Gewinnt: Spielsteine setzen

    Hi,

    hab folgendes Problem bei meinem 4Gewinnt Programm.
    Ich setze einen Spielstein über die Horizontale und dieser soll rein theoretisch soweit in die Vertikale voranschreiten bis er das Ende des Spielfeldes oder auf einen anderen Spielstein trifft.
    Nun ist es aber, dass wenn er auf einen anderen Spielstein trifft, dass dieser ersetzt wird, was aber nicht sein soll.

    Quellcode

    1. int CGameField::checkVerticalLines(int j){
    2. int i=0;
    3. while(i != 9){
    4. if(GameField[j][i] == 0){
    5. ++i;
    6. }
    7. else{
    8. return --i;
    9. }
    10. };
    11. return i;
    12. }
    Alles anzeigen

    Die freien Spielfelder sind mit 0 gekenntzeichnet.
    Hab ich irgendwo einen Denkfehler?

    cheers
    nobody

    Edit://
    Ich habe herausgefunden, das der Wert der zurückgeben wird, zwar in GameField gespeichert wird, sobald aber die Methode nochmals aufgerufen wird, ist GameField nur mit dem Standardwert 0 belegt und das auch nur in dieser Methode.
    Woran könnte das liegen, das sich die Werte, die sich innerhalb und außerhalb der Methode befinden, unterscheiden?
    "Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von nobody special ()

  • GameField ist in der Headerdatei als private Member deklariert.


    ich hatte nochmal zwischen zeitliche leichte Änderungen vorgenommen.
    MIttlerweile sieht der Code nun so aus.

    Quellcode

    1. int CGameField::checkVerticalLines(int *j){
    2. int i = 0;
    3. while(i != 9)
    4. {
    5. if( GameField[i][*j] == 0){
    6. ++i;
    7. }
    8. else
    9. {
    10. --i;
    11. break;
    12. }
    13. }
    14. return i;
    15. }
    Alles anzeigen


    Das ist die Methode die checkVerticalLines aufruft und das ergebniss in GameField speichert.

    Quellcode

    1. bool CGameField::setChip(int X, int Player){
    2. int Y = checkVerticalLines(&X);
    3. GameField[Y][X] = Player;


    Die Adressen innerhalb der Methode und außerhalb sind identisch.
    "Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von nobody special ()

  • Das Problemliegt an:
    while(i != 9)

    Wenn noch kein Stein gelegt sind kriegst du 9 zurück, dein Feld ist jedoch 8*8 (0..7) groß.
    Du erhälst neben einem falschen Index dann auch eine Speicherverletzung.

    PS: Bennen mal deine Zählvariablen gleich (X=i? Y=j? oder doch nicht Oo)

    Quellcode

    1. int checkVerticalLines(const int j){
    2. int i=0;
    3. for (; i<8; i++)
    4. {
    5. if (GameField[j][i] != 0)
    6. break;
    7. }
    8. return i-1;
    9. }
    10. bool setChip(int j, int Player)
    11. {
    12. int i = checkVerticalLines(j);
    13. if (i>=0)
    14. GameField[j][i] = Player;
    15. else
    16. return false;
    17. return true;
    18. }
    Alles anzeigen


    Kannst ja versuchen das auf dein Algorithmus zu übertragen.


    Mfg Rushh0ur
  • So simpel ist es leider auch nicht....
    Mein 2dArray hat die Größe von 10x10.
    Wenn es 8x8 hätte würde er die unterste Reihe mit steinen ja nicht anzeigen.
    Außerdem würde sicherlich doch ne Fehlermeldung oder Warnung kommen wenn ich
    außerhalb des gültigen Speicherbereiches versuchen würde einen Schreibzugriff zumachen oder?
    Und das hät ich dann auch bemerkt....

    Ausschnitt aus Header

    Quellcode

    1. private: static const int Max = 10;
    2. const int Gamemode;
    3. int Counter;
    4. int GameField[Max][Max];


    Das mit den Zählvariablen muss ich mal ändern.. sieht wirklich nicht schön aus und verwirrt.
    "Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer."
  • Hallo,

    ich war in letzter Zeit ziemlich beschäftigt und hatte keine Zeit um mich weiter um mein Problem, welches immer noch besteht, zu kümmern.
    Wie gesagt das selbe Problem wie seit Wochen. Meine Spielsteine auf der untersten Ebene werden von den neuen Spielsteinen ersetzt, anstatt das diese neuen Steine eine Ebene weiter oben platziert werden.
    Ich werde jetzt einfach mal die gesamte Klasse Gamefield posten. Vielleicht versteckt sich ja der Fehler auch irgendwo anderest.
    Ich hoffe ihr könnt mir helfen.

    Quellcode

    1. #include "CGameField.h"
    2. #include <iostream>
    3. CGameField::CGameField() : Gamemode(4),Counter(0)
    4. {}
    5. CGameField::~CGameField()
    6. {
    7. }
    8. CGameField::CGameField(int Mode) : Gamemode(Mode),Counter(0)
    9. {
    10. }
    11. void CGameField::initializeGamefield(){
    12. for (int i = 0; i < Max; ++i){
    13. for (int j = 0; j < Max; ++j){
    14. GameField[i][j] = 0;
    15. }
    16. }
    17. }
    18. int CGameField::checkVerticalLines(int *j){
    19. int i = 0;
    20. while(i != 9)
    21. {
    22. if( GameField[i][*j] == 0){
    23. ++i;
    24. }
    25. else
    26. {
    27. --i;
    28. break;
    29. }
    30. }
    31. return i;
    32. }
    33. bool CGameField::setChip(int j, int Player){
    34. int i = checkVerticalLines(&j);
    35. GameField[i][j] = Player;
    36. ++Counter;
    37. if(Counter == 99){
    38. std::cout<<"Unentschieden\n";
    39. printGamefield();
    40. return true;
    41. }
    42. if(checkHor(&j,&i,&Player)){
    43. std::cout<<"Spieler "<<Player<<" hat gewonnen\n";
    44. printGamefield();
    45. return true;
    46. }
    47. if(checkVer(&j,&i,&Player)){
    48. std::cout<<"Spieler "<<Player<<" hat gewonnen\n";
    49. printGamefield();
    50. return true;
    51. }
    52. if(checkDia(&j,&i,&Player)){
    53. std::cout<<"Spieler "<<Player<<" hat gewonnen\n";
    54. printGamefield();
    55. return true;
    56. }
    57. return false;
    58. }
    59. bool CGameField::checkHor(int *X, int *Y, int *Player){
    60. int Counter = 0;
    61. int n=0;
    62. while(GameField[*Y][*X+n]==*Player){
    63. ++Counter;
    64. ++n;
    65. }
    66. n=1;
    67. while(GameField[*Y][*X-n]==*Player){
    68. ++Counter;
    69. ++n;
    70. }
    71. if(Counter >= Gamemode){return true;}
    72. return false;
    73. }
    74. bool CGameField::checkVer(int *X, int *Y, int *Player){
    75. int Counter = 0;
    76. int n=0;
    77. while(GameField[*Y+n][*X]==*Player){
    78. ++Counter;
    79. ++n;
    80. }
    81. n=1;
    82. while(GameField[*Y-n][*X]==*Player){
    83. ++Counter;
    84. ++n;
    85. }
    86. if(Counter >= Gamemode){return true;}
    87. return false;
    88. }
    89. bool CGameField::checkDia(int *X, int *Y, int *Player){
    90. int Counter = 0;
    91. int n=0;
    92. while(GameField[*Y+n][*X+n]==*Player){
    93. ++Counter;
    94. ++n;
    95. }
    96. n=1;
    97. while(GameField[*Y-n][*X-n]==*Player){
    98. ++Counter;
    99. ++n;
    100. }
    101. if(Counter >= Gamemode){return true;}
    102. return false;
    103. }
    104. void CGameField::printGamefield(){
    105. std::cout<<"0123456789";
    106. std::cout<<"\n------------\n";
    107. for(int i = 0; i< 10;++i){
    108. for (int j = 0; j< 10; ++j){
    109. std::cout<<GameField[i][j];
    110. }
    111. std::cout<<"\n";
    112. }
    113. std::cout<<"\n";
    114. }
    115. int* CGameField::getGameField(){
    116. return *GameField;
    117. }
    Alles anzeigen


    Greetz
    nodody
    "Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer."