우선, 여기서 디버깅 도움을 요청할 수 있기를 바랍니다. 그 말로, 나는이 간단한 tic tac toe 프로그램을 만들었고 기본적으로 끝났지 만,이 의미 론적 오류로 인해 나를 죽였다. ,Java에서 기본 Tictactoe 프로그램의 의미 오류
는 물론, 난 내 자신의 문제를 알아 내려고 시간을 소비했지만, 그래서 여기에 지금입니다 :) 몇 가지 간단한 개요를
당신은 내가 그 포기했다고 말할 수 있습니다 보드는 char ttt [3] [3] 타입의 배열로 표현된다. 플레이어는 char 형의 변수, 그래서 그들은 문자로 입력되는 'X'또는 'O'와 보드의 좌표 중 하나입니다 :
샘플 실행은 다음과 같이 표시됩니다
********************************
---a------b------c---
| | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
a
********************************
---a------b------c---
| O | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
array ttt [3] [3]은 모든 원소가 단지 ''가되도록 초기화됩니다.
대부분 프로그램이 제대로 실행됩니다. 너희들을위한 시간을 절약하려고, 나는 다음과 같은 방법
- 부울 승자 (문자 플레이어)
- 부울 gameIsDraw()
- 무효 displayBoard()
- 완벽하게 실행되고 있는지 확신 문자열 playerID (문자 플레이어)
- 및 주요 방법 나는 문제를보고 할
은 대부분 내,536에 포함되어getPlayerInput (char player) 메서드 :
void getPlayerInput(char player)
{
int row = 0;
int col = 0;
System.out.println(playerID(player) + ", it is your turn.");
System.out.println("Select a cell [a, b, c, ... i]");
char answer;
answer = scan.next().charAt(0);
switch(answer)
{
case 'a':
row = 0;
col = 0;
break;
case 'b':
row = 0;
col = 1;
break;
case 'c':
row = 0;
col = 2;
break;
case 'd':
row = 1;
col = 0;
break;
case 'e':
row = 1;
col = 1;
break;
case 'f':
row = 1;
col = 2;
break;
case 'g':
row = 2;
col = 0;
break;
case 'h':
row = 2;
col = 1;
break;
case 'i':
row = 2;
col = 2;
break;
default:
System.out.println("Invalid location, try again.");
getPlayerInput(player);
}
if(ttt[row][col] != ' ')
{
System.out.println("This square is taken. Try again.");
getPlayerInput(player);
}
else
{
ttt[row][col] = player;
}
}
내게는 괜찮은 것처럼 보이지만 출력 결과는 그렇지 않다는 것을 나타냅니다. 이 방법은 두 failsafes,
를 포함하는 경우, 기판 영역 외부의 사용자 입력의 일 ("A"내지 "I"의 외부 문자)
또는
사용자가 문자/위치를 선택하면 이미 다른 'X'또는 'O'에 의해 채택 된 보드에.
두 경우 모두 잘못된 입력이 입력되었다는 것을 인쇄하고 getPlayerInput()을 다시 호출합니다.
디버깅을 통해주의해야 할 것은 유효한 입력 만 입력하면 프로그램이 정상적으로 실행되는 것입니다. 그러나 잘못된 입력 (두 유형 모두)이 입력 된 후 유효한 입력이 입력되면, 때때로이 메소드는 잘못된 입력이 여전히 입력되었음을 인쇄합니다. 예를 들어
, I는 문자 입력
********************************
---a------b------c---
| | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
a
********************************
---a------b------c---
| O | | |
---d------e------f---
| | | |
---g------h------i---
| | | |
---------------------
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
z
Invalid location, try again.
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
e
This square is taken. Try again.
player2: X, it is your turn.
Select a cell [a, b, c, ... i]
f
********************************
---a------b------c---
| O | | |
---d------e------f---
| | X | X |
---g------h------i---
| | | |
---------------------
player1: O, it is your turn.
Select a cell [a, b, c, ... i]
공지 A-Z-E-F이다. 'z'는 분명히 유효하지 않은 문자이므로 메서드가 의도 한대로 작동하고 (지금까지) 유효하지 않은 입력으로 인쇄 된 다음 메서드가 다시 실행되어 입력을 요청합니다. 분명히 유효한 위치 인 'e'가 입력되었지만, 분명히 그렇지 않은 경우에는 "사각형이 이미 찍혔다"는 방법이 인쇄되었습니다. 그러나 다른 숯불 'f'를 입력하면 나에게 그것을 허용했다.
최종 결과는 플레이어 'X'가 2 회전하고 'e'와 'f'두 칸을 채 웁니다.
사용자가 지속적으로 잘못된 입력을 입력하면 유효한 입력이 입력 될 때까지 해당 방법을 고수해야하지만 이는 잘못된 입력이 잘못된 입력으로 잘못 해석 된 경우와 분명히 다릅니다. 좋은 입력의 다른 인스턴스가 입력되지 않으면 루프를 종료 할 수 없습니다.
그래서 모든 것이 도움이되었습니다.
import java.util.*;
class TicTacToe
{
char ttt[][] = new char[3][3];
static final char player1 = 'O';
static final char player2 = 'X';
Scanner scan =new Scanner(System.in);
String playerID(char player)
{
if (player == player1)
return "player1: "+player;
else
return "player2: "+ player;
}
void getPlayerInput(char player)
{
int row = 0;
int col = 0;
System.out.println(playerID(player) + ", it is your turn.");
System.out.println("Select a cell [a, b, c, ... i]");
char answer;
answer = scan.next().charAt(0);
switch(answer)
{
case 'a':
row = 0;
col = 0;
break;
case 'b':
row = 0;
col = 1;
break;
case 'c':
row = 0;
col = 2;
break;
case 'd':
row = 1;
col = 0;
break;
case 'e':
row = 1;
col = 1;
break;
case 'f':
row = 1;
col = 2;
break;
case 'g':
row = 2;
col = 0;
break;
case 'h':
row = 2;
col = 1;
break;
case 'i':
row = 2;
col = 2;
break;
default:
System.out.println("Invalid location, try again.");
getPlayerInput(player);
}
if(ttt[row][col] != ' ')
{
System.out.println("This square is taken. Try again.");
getPlayerInput(player);
}
else
{
ttt[row][col] = player;
}
}
boolean gameIsDraw()
{
boolean isDraw = true;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(ttt[i][j] == ' ')
{
isDraw = false;
}
}
}
return isDraw;
}
boolean winner(char player)
{
boolean hasWon = false;
// possible horizontal wins
for(int i = 0; i < 3; i++)
{
if(ttt[i][0] == player && ttt[i][1] == player && ttt[i][2] == player)
{
hasWon = true;
}
}
// possible vertical wins
for(int i = 0; i < 3; i++)
{
if(ttt[0][i] == player && ttt[1][i] == player && ttt[2][i] == player)
{
hasWon = true;
}
}
// one diagonal win
if(ttt[0][0] == player && ttt[1][1] == player && ttt[2][2] == player)
{
hasWon = true;
}
// other diagonal win
if(ttt[0][2] == player && ttt[1][1] == player && ttt[2][0] == player)
{
hasWon = true;
}
return hasWon;
}
void displayBoard()
{
System.out.println("********************************");
System.out.println(" ---a------b------c---");
for (int i=0; i<3; i++)
{
for (int j=0; j< 3; j++)
{
if (j == 0) System.out.print(" | ");
System.out.print(ttt[i][j]);
if (j < 2) System.out.print(" | ");
if (j==2) System.out.print(" |");
}
System.out.println();
switch (i)
{
case 0:
System.out.println(" ---d------e------f---");
break;
case 1:
System.out.println(" ---g------h------i---");
break;
case 2:
System.out.println(" ---------------------");
break;
}
}
}
void newgame()
{
char currPlayer = player1;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
ttt[i][j] =' ';
boolean continueFlag = true;
while (continueFlag)
{
displayBoard();
if (gameIsDraw())
{
System.out.println("Game Ends in Draw");
continueFlag = false;
}
else
{
getPlayerInput(currPlayer);
if (winner(currPlayer))
{
System.out.println("We have a winner: " + playerID(currPlayer));
displayBoard();
continueFlag = false;
}
else
{
if (currPlayer == player1) currPlayer = player2;
else currPlayer = player1;
}
}
}
}
public static void main(String[] args)
{
TicTacToe game = new TicTacToe();
String str;
do
{
game.newgame();
System.out.println("Do you want to play Tic-Tac-Toe (y/n)?");
str= game.scan.next();
} while ("y".equals(str));
System.out.println("Bye");
}
}
감사합니다! 당신의 도움 외에도, 나는 그것에 잠을 자고 그것을 알아 냈습니다. 불행히도 당신의 제안은 불행하게도 잘못된 입력이 입력되면 if-statement가 범위를 벗어난 위치를 검사하기 때문에 런타임 오류가 발생하지만 다른 while 루프에서는 쉽게 해결할 수 있습니다. 재귀 대신에 반복을 사용하는 것이 핵심 아이디어였습니다. 재귀가 왜 유효한 전략이 아닌지에 대한 설명을 제공 할 수 있다면 여전히 가능합니까? – HelloMyNameIsRay
더 많은 설명을 추가하고 코드를 수정했습니다. 어쨌든 RuntimeException은 당신이 원하는 것입니다! 뭔가 잘못되어 열심히 실패했습니다. 원래 코드에서 row, column은 처음에는 0,0으로 설정되었으므로 잘못된 입력은 항상 0,0 제곱에서 재생하려고 시도합니다. 그 사각형이 잡히면 재귀 호출은 사용자에게 두 번째 재귀 호출 (다시 스위치의 기본 블록에서 첫 번째 호출이 발생 함)이있는 다른 기회를 사용자에게 제공합니다. 기본적으로 사용자가 입력 시도를 두 배로 늘립니다. –