我最近做了一个Connect 4游戏。但是,我将所有代码都放在一个Java文件/类中。我现在正在尝试重构代码,以便将不同的代码操作分成不同的类。例如玩,玩和玩游戏。
有人可以向我解释为什么我收到以下错误吗?
Exception in thread "main" java.lang.StackOverflowError
at java.nio.Buffer.<init>(Buffer.java:201)
at java.nio.ByteBuffer.<init>(ByteBuffer.java:281)
at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
at java.nio.ByteBuffer.allocate(ByteBuffer.java:335)
at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:251)
at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:231)
at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:69)
at java.io.InputStreamReader.<init>(InputStreamReader.java:74)
at Connect4Game.<init>(Connect4Game.java:19)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
at Connect4Game.<init>(Connect4Game.java:21)
at play.<init>(play.java:2)
如果将方向正确指向我会非常感激,因为这是我第一次将工作代码重构为多个类。
这是我的代码:
Connect4Game.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Connect4Game {
final int boardWidth=7;
final int boardHeight=7;
int totalMovesPlayed;
public BufferedReader input;
public char[][] board;
public static void main(String[] args){
new Connect4Game();
}
public Connect4Game(){
board = new char[6][7];
input = new BufferedReader(new InputStreamReader(System.in));
play PlayObj = new play();
PlayObj.playGame();
}
}
play.java
public class play extends Connect4Game {
public void playGame() {
System.out.println("Welcome to Connect 4");
System.out.println("To play the game type in the number of the column you want to drop you counter in");
System.out.println("Player One = r Player 2 = y");
System.out.println("");
board boardObj = new board();
boardObj.printBoard();
boolean win = false;
while(!win){
// player 1
String userInput = getUserInput();
int move = Integer.parseInt(userInput);
counter counterObj = new counter();
counterObj.placeCounter('r', move);
boolean hasWon = false;
int count = 0;
// check horizontal
for(int i=0; i<board.length; i++){
for(int j=0; j<board[i].length; j++){
if(board[i][j] == 'r'){
count = count + 1;
if(count == 4){
hasWon = true;
System.out.println("You Have Won!!!");
}
}
else{
count = 0;
}
}
}
// check vertical
count = 0;
for(int i=0; i<board[0].length; i++){
for(int j=0; j<board.length; j++){
if(board[j][i] == 'r'){
count = count + 1;
if(count >= 4){
hasWon = true;
System.out.println("You Have Won!!!");
}
}
else{
count = 0;
}
}
}
boardObj.printBoard();
if(hasWon){
win = true;
System.out.println("You Have Won!!!");
}
else {
//player 2
userInput = getUserInput();
move = Integer.parseInt(userInput);
counterObj.placeCounter('y',move);
hasWon = false;
count = 0;
// check horizontal
for(int i=0; i<board.length; i++){
for(int j=0; j<board[i].length; j++){
if(board[i][j] == 'y'){
count = count + 1;
if(count >= 4){
hasWon = true;
System.out.println("You Have Won!!!");
}
}
else{
count = 0;
}
}
}
// check vertical
count = 0;
for(int i=0; i<board[0].length; i++){
for(int j=0; j<board.length; j++){
if(board[j][i] == 'y'){
count = count + 1;
if(count >= 4){
hasWon = true;
System.out.println("You Have Won!!!");
}
}
else{
count = 0;
}
}
}
boardObj.printBoard();
if(hasWon){
win = true;
System.out.println("You Have Won!!!");
}
}
}
}
public String getUserInput(){
String toReturn = null;
try{
toReturn = input.readLine();
}
catch(Exception e){
}
return toReturn;
}
}
board.java
public class board extends Connect4Game {
public void printBoard(){
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
if(board[i][j] == 0)
System.out.print(". ");
else
System.out.print(board[i][j]+" ");
}
System.out.println();
}
for(int i=0;i<boardWidth;i++)
System.out.print("* ");
System.out.println();
for(int i=0;i<boardWidth;i++)
System.out.print(i+" ");
System.out.println();
}
}
counter.java
public class counter extends Connect4Game {
public void placeCounter(char player, int position){
boolean placed = false;
if(player == 'r'){
for( int i=board.length-1; i>=0; i--){
if(!placed && board[i - 1][position] != 'r' && board[i - 1][position] != 'y') {
if(board[i][position] == 'y'){
board[i-1][position] = 'r';
placed = true;
}
else if(board[i][position] != 'r'){
board[i][position] = 'r';
placed = true;
}
}
}
}
else {
for( int i=board.length-1; i>=0; i--){
if (!placed && board[i - 1][position] != 'r' && board[i - 1][position] != 'y'){
if(board[i][position] == 'r'){
board[i-1][position] = 'y';
placed = true;
}
else if(board[i][position] != 'y'){
board[i][position] = 'y';
placed = true;
}
}
}
}
}
}
答案 0 :(得分:4)
在Connect4Game
的构造函数中,您正在调用子类play
的构造函数,但是该子类没有自己的构造函数,因此实际上您在为Connect4Game
再次调用相同的构造函数,然后调用自身,依此类推,直到出现堆栈溢出
public Connect4Game(){
board = new char[6][7];
input = new BufferedReader(new InputStreamReader(System.in));
play PlayObj = new play();
PlayObj.playGame();
}
您的main方法应直接创建一个play对象,然后调用playGame方法
public static void main(String[] args){
play PlayObj = new play();
PlayObj.playGame()
}
请遵循Java命名标准,并以大写字母开头您的分类
答案 1 :(得分:4)
play扩展了Connect4Game。 因此,当实例化一个新的游戏对象时,这也会调用Connect4Game的无参数构造函数。 此Connect4Game()构造函数实例化一个新的游戏对象,该对象又再次实例化一个新的Connect4Game。因此,您已经建立了一个递归构造循环。
我认为游戏不应从Connect4Game扩展。播放实例不是Connect4Game的特定类型,因此在此处无需扩展它。
事实上,我认为其他任何类都不应该从Connect4Game扩展。
如果希望其他类可以访问开发板和输入变量,则应将Connect4Game作为构造函数参数传递给这些实例:
public class play {
private Connect4Game connect;
public play(Connect4Game connect) {
this.connect=connect;
}
...
}
然后,您可以在代码中使用connect.board
而不是单板。
您的主要代码将变为:
public static void main(String[] args){
Connect4Game connect=new Connect4Game();
play PlayObj = new play(connect);
PlayObj.playGame();
}
public Connect4Game(){
board = new char[6][7];
input = new BufferedReader(new InputStreamReader(System.in));
}
您的董事会课程很难阅读。您的类名称应以大写字母开头,实例变量以小写字母开头。
对于您的董事会班,这可能变成:
public class Board {
private Connect4Game connect;
public Board(Connect4Game connect) {
this.connect=connect;
}
// to refer to the board variable of Connect4Game:
connect.board
}
现在您可以问自己是否使用了此类Class Board?