作为自学经验,我构建了一个 3x3 TicTacToe 游戏。现在我想将该游戏扩展到 N x N 大小的棋盘。在确定获胜条件时,这给我带来了一个问题。
原始游戏使用数组来寻找获胜条件:
private final int[][] win = new int[][] {
{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, //horizontal
{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, //vertical
{0, 4, 8}, {2, 4, 6} //diagonal
};
在 ActionListener 中:
// Check the win array for 3-in-a-line condition.
for(int i = 0; i<=7; i++){
if( b[win[i][0]].getText().equals( b[win[i][1]].getText() ) && // A == B
b[win[i][1]].getText().equals( b[win[i][2]].getText() ) && // B == C
!b[win[i][0]].getText().equals("")){ // Not empty
b[win[i][0]].setBackground(Color.GREEN);
b[win[i][1]].setBackground(Color.GREEN);
b[win[i][2]].setBackground(Color.GREEN);
gameOver = true;
System.out.println("WIN WIN WIN");
随着游戏扩展到 N x N 大小,我不能有一个固定的数组来确定获胜条件。
我需要一些程序来确定一行中是否有 3 个(或更多)。那么你将如何处理这个问题?有没有更聪明的方法来做到这一点,而不是检查所有最接近放置的方块?(北+南、东+西、N+N、E+E、S+S、W+W、NE+SW、NW+SE、NE+NE、NW+NW、SE+SE、SW+SW)和尝试过滤掉所有的PointerExceptions?
每次检查整个板子,控制for循环的索引不越界?
这两种解决方案都像是编码的噩梦。有人对这个问题有更聪明的方法吗?
添加整个程序以供参考:
package heniv181;
import javax.swing.JFrame;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JOptionPane;
/**
* @author Henrik
* Also code by John (john@codecall.net) http://forum.codecall.net/topic/36472-javatutorial-tic-tac-toe/
*
*/
public class TicTacToeBig extends JFrame
implements ActionListener {
private int size = 5;
private JButton[] b = new JButton[size*size];
private int turn = 0;
private final int[][] win = new int[][] {
{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, //horizontal
{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, //virticle
{0, 4, 8}, {2, 4, 6} //diagonal
};
// Constructor
public TicTacToeBig(){
setTitle("Tic-Tac-Toe");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
setLocation(200, 200);
setVisible(true);
setLayout(new GridLayout(size,size));
for(int i=0; i < size*size; i++){
b[i] = new JButton();
b[i].setText("");
b[i].addActionListener(this);
b[i].setActionCommand( Integer.toString(i));
add(b[i]);
}
}
public static void main(String args[]){
TicTacToeBig t = new TicTacToeBig();
}
@Override
public void actionPerformed(ActionEvent ae) {
String sign;
boolean gameOver = false;
// Whos turn is it? X's or O's?
turn++;
if(turn % 2 == 0)
sign="X";
else
sign="O";
// Set X or O on the button pressed.
JButton press = (JButton)ae.getSource();
press.setText(sign);
press.setEnabled(false);
gameOver = checkWin(press);
/* Check the win array for 3-in-a-line condition.
for(int i = 0; i<=7; i++){
if( b[win[i][0]].getText().equals( b[win[i][1]].getText() ) && // A == B
b[win[i][1]].getText().equals( b[win[i][2]].getText() ) && // B == C
!b[win[i][0]].getText().equals("")){ // Not empty
b[win[i][0]].setBackground(Color.GREEN);
b[win[i][1]].setBackground(Color.GREEN);
b[win[i][2]].setBackground(Color.GREEN);
gameOver = true;
System.out.println("WIN WIN WIN");
}
}*/
//End game if winning conditon is true or no more turns.
if(gameOver){
JOptionPane.showMessageDialog(null, "Congratulation!\n" + sign + " have won!");
System.exit(0);
}
else if(turn>=(size*size) ){
JOptionPane.showMessageDialog(null, "To bad!\n No winners. ");
System.exit(0);
}
}
public boolean checkWin(JButton j){
//HHmmmm..........
int index = Integer.valueOf( j.getActionCommand() );
System.out.println(index);
if((index+1) % size == 0 || (index+1) % size == 1)
System.out.println("R or L Edge.");
if(index-size < 0 || index+size > b.length-1)
System.out.println("U or D Edge");
//check right and left
//check if point is on right or left edge
//compare index-1 L
//compare index+1 R
//check up and down
//check if point is on top or bottom edge
//compare index - size D
//compare index + size U
//check diagonals
//check if point is on edge
//compare index - size -1 UL
//compare index - size +1 UR
//compare index + size -1 DL
//compare index + size +1 DR
return false;
}
}