我必须使用模拟智能实现connect4。它已经有效,但速度很慢。我们必须得到两个玩家的威胁。威胁是行中3个硬币,行末端或行尾有空字段。我想在每次移动后只计算新的威胁,并删除不再受到威胁的威胁。如果最后一步有新的威胁,我会写一些方法来检查每个方向。
private Field row(int row, int column, String Player) {
Field field = null;
if(column - 1 >= 0 && column + 1 < board.getColumn() && board.getValue(row, column-1).equals(Player)
&& board.getValue(row, column+1).equals(Player)) {
if(column -2 >= 0 &&board.getValue(row, column-2).equals(" ")) {
return field = new Field(row, column -2);
}
else if(column + 2 < board.getColumn()&& board.getValue(row, column+2).equals(" ")) {
return field = new Field(row, column +2);
}
}
else if(column - 2 >= 0 && board.getValue(row, column-1).equals(Player)
&& board.getValue(row, column-2).equals(Player)) {
if(column -3 >= 0 &&board.getValue(row, column-3).equals(" ")) {
return field = new Field(row, column -3);
}
else if(column +1 < board.getColumn()&& board.getValue(row, column+1).equals(" ")) {
return field = new Field(row, column +1);
}
}
else if(column +2 < board.getColumn() && board.getValue(row, column+1).equals(Player)
&& board.getValue(row, column+2).equals(Player)) {
if(column -1 >= 0 &&board.getValue(row, column-1).equals(" ")) {
return field = new Field(row, column -1);
}
else if(column +3 < board.getColumn()&& board.getValue(row, column+3).equals(" ")) {
return field = new Field(row, column +3);
}
}
else if(column - 2 >= 0 && column + 1 < board.getColumn() && board.getValue(row, column-2).equals(Player)
&& board.getValue(row, column+1).equals(Player)) {
if(column -1 >= 0 &&board.getValue(row, column-1).equals(" ")) {
return field = new Field(row, column -1);
}
}
else if(column - 1 >= 0 && column +2 < board.getColumn() && board.getValue(row, column-1).equals(Player)
&& board.getValue(row, column+2).equals(Player)) {
if(column +1 < board.getColumn() &&board.getValue(row, column+1).equals(" ")) {
return field = new Field(row, column +1);
}
}
else if(column - 3 >= 0 && board.getValue(row, column-2).equals(Player) && board.getValue(row, column-3).equals(Player)) {
if(board.getValue(row, column-1).equals(" ")) {
return new Field (row, column -1);
}
}
else if(column-3 >= 0 && board.getValue(row, column-1).equals(Player) && board.getValue(row, column-3).equals(Player)) {
if(board.getValue(row, column-2).equals(" ")) {
return new Field(row, column - 2);
}
}
else if(column + 3 < board.getColumn() && board.getValue(row, column+2).equals(Player) && board.getValue(row, column+3).equals(Player)) {
if(board.getValue(row, column+1).equals(" ")) {
return new Field(row, column + 1);
}
}
else if(column + 3 < board.getColumn() && board.getValue(row, column+1).equals(Player) && board.getValue(row, column+3).equals(Player)) {
if(board.getValue(row, column+2).equals(" ")) {
return new Field(row, column +2);
}
}
return field;
}
private Field column(int row, int column, String Player) {
Field field = null;
if (row + 2 < board.getRow()
&& board.getValue(row + 1, column).equals(Player)
&& board.getValue(row + 2, column).equals(Player)) {
if(row-1 >= 0 && board.getValue(row-1, column).equals(" ")) {
return field = new Field(row-1, column);
}
}
return field;
}
private Field diagonalRight(int row, int column, String Player) {
Field field = null;
if(row - 1 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 1 < board.getColumn()
&& board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row-1, column+1).equals(Player)) {
if(row + 2 < board.getRow() && column - 2 >= 0 && board.getValue(row+2, column-2).equals(" ")) {
return field = new Field(row+2, column - 2);
}
else if (row - 2 >=0 && column + 2 < board.getColumn() && board.getValue(row-2, column+2).equals(" ")) {
return field = new Field(row-2, column + 2);
}
}
else if(row + 2 < board.getRow() && column - 2 >= 0 && board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row+2, column-2).equals(Player)) {
if(row +3 < board.getRow() && column - 3 >= 0 && board.getValue(row+3, column-3).equals(" ")) {
return field = new Field(row+3, column - 3);
}
else if (row - 1 >=0 && column + 1 < board.getColumn() && board.getValue(row-1, column+1).equals(" ")) {
return field = new Field(row-1, column + 1);
}
}
else if(row - 2 >= 0 && column +2 < board.getColumn() && board.getValue(row- 1, column+1).equals(Player)&& board.getValue(row-2, column+2).equals(Player)) {
if(row -3>= 0 && column + 3 < board.getColumn() && board.getValue(row-3, column+3).equals(" ")) {
return field = new Field(row-3, column +3);
}
else if (row + 1 < board.getRow() && column -1 >=0 && board.getValue(row+1, column-1).equals(" ")) {
return field = new Field(row+1, column -1);
}
}
else if(row - 2 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 2 < board.getColumn()
&& board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row-2, column+2).equals(Player)) {
if (row - 1 >=0 && column + 1 < board.getColumn() && board.getValue(row-1, column+1).equals(" ")) {
return field = new Field(row-1, column + 1);
}
}
else if(row + 2 < board.getRow() && column -2 >= 0 && row - 1 >= 0 && column + 1 < board.getColumn()
&& board.getValue(row+ 2, column-2).equals(Player)&& board.getValue(row-1, column+1).equals(Player)) {
if (row + 1 < board.getRow() && column - 1 >= 0 && board.getValue(row+1, column-1).equals(" ")) {
return field = new Field(row+1, column - 1);
}
}
else if(row + 3 < board.getRow() && column + 3 < board.getColumn() && board.getValue(row + 2, column+2).equals(Player) && board.getValue(row+3, column+3).equals(Player)) {
if( board.getValue(row+1, column+1).equals(" ")) {
return new Field(row+1, column +1);
}
}
else if(row + 3 < board.getRow() && column + 3 < board.getColumn() && board.getValue(row+3, column+3).equals(Player) && board.getValue(row+1, column+1).equals(Player)) {
if(board.getValue(row+2, column+2).equals(" ")) {
return new Field (row +2, column + 2);
}
}
else if(row - 3 >= 0 && column - 3 >= 0 && board.getValue(row-3, column-3).equals(Player) && board.getValue(row-2, column-2).equals(Player)) {
if(board.getValue(row-1, column-1).equals(" ")) {
return new Field(row-1, column -1);
}
}
else if(row-3 >=0 && column -3>= 0 && board.getValue(row-3, column-3).equals(Player) && board.getValue(row-1, column-1).equals(Player)) {
if(board.getValue(row-2, column-2).equals(" ")) {
return new Field (row-2, column - 2);
}
}
return field ;
}
private Field diagonalLeft(int row, int column, String Player) {
Field field = null;
if(row - 1 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 1 < board.getColumn()
&& board.getValue(row+ 1, column+1).equals(Player)&& board.getValue(row-1, column-1).equals(Player)) {
if(row + 2 < board.getRow() && column + 2 < board.getColumn() && board.getValue(row+2, column+2).equals(" ")) {
return field = new Field(row+2, column + 2);
}
else if (row - 2 >=0 && column - 2 >=0 && board.getValue(row-2, column-2).equals(" ")) {
return field = new Field(row-2, column - 2);
}
}
else if(row + 2 < board.getRow() && column + 2 < board.getColumn()&& board.getValue(row+ 1, column+1).equals(Player)&& board.getValue(row+2, column+2).equals(Player)) {
if(row +3 < board.getRow() && column + 3 < board.getColumn() && board.getValue(row+3, column+3).equals(" ")) {
return field = new Field(row+3, column + 3);
}
else if (row - 1 >=0 && column - 1 >=0 && board.getValue(row-1, column-1).equals(" ")) {
return field = new Field(row-1, column - 1);
}
}
else if(row - 2 >= 0 && column -2 >=0 && board.getValue(row- 1, column-1).equals(Player)&& board.getValue(row-2, column-2).equals(Player)) {
if(row -3>= 0 && column - 3 >= 0 && board.getValue(row-3, column-3).equals(" ")) {
return field = new Field(row-3, column -3);
}
else if (row + 1 < board.getRow() && column +1 <board.getColumn() && board.getValue(row+1, column+1).equals(" ")) {
return field = new Field(row+1, column +1);
}
}
else if(row - 1 >= 0 && column - 1 >= 0 && row + 2 < board.getRow() && column + 2 < board.getColumn()
&& board.getValue(row- 1, column-1).equals(Player)&& board.getValue(row+2, column+2).equals(Player)) {
if (row + 1 < board.getRow() && column + 1 < board.getColumn() && board.getValue(row+1, column+1).equals(" ")) {
return field = new Field(row+1, column + 1);
}
}
else if(row + 1 < board.getRow() && column -2 >= 0 && row - 2 >= 0 && column + 1 < board.getColumn()
&& board.getValue(row- 2, column-2).equals(Player)&& board.getValue(row+1, column+1).equals(Player)) {
if (row - 1 >= 0 && column - 1 >= 0 && board.getValue(row-1, column-1).equals(" ")) {
return field = new Field(row-1, column - 1);
}
}
else if(row - 3 >=0 && column + 3 < board.getColumn() && board.getValue(row - 2, column+2).equals(Player) && board.getValue(row-3, column+3).equals(Player)) {
if( board.getValue(row-1, column+1).equals(" ")) {
return new Field(row-1, column +1);
}
}
else if(row - 3 >=0 && column + 3 < board.getColumn() && board.getValue(row-3, column+3).equals(Player) && board.getValue(row-1, column+1).equals(Player)) {
if(board.getValue(row-2, column+2).equals(" ")) {
return new Field (row -2, column + 2);
}
}
else if(row + 3 < board.getRow() && column - 3 >= 0 && board.getValue(row+3, column-3).equals(Player) && board.getValue(row+2, column-2).equals(Player)) {
if(board.getValue(row+1, column-1).equals(" ")) {
return new Field(row+1, column -1);
}
}
else if(row+3 < board.getRow() && column -3>= 0 && board.getValue(row+3, column-3).equals(Player) && board.getValue(row+1, column-1).equals(Player)) {
if(board.getValue(row+2, column-2).equals(" ")) {
return new Field (row+2, column - 2);
}
}
return field;
}
方法真的很高,也有错误......但我找不到它。你能给我一些提示,告诉我如何更好地实施这些方法吗? 谢谢
编辑1:
perhebs你应该只看第一种方法。我采取最后一步行动,检查是否包含最后一步的威胁。所以如果在同一个玩家的行中有两个以上的硬币会造成威胁,我就会嗤之以鼻。大A是最后一个Move,我想检查teh是否是小a,以便他们制造威胁:
| | a | A | a | | | | 例如,我检查A的字段右边是a是否A的字段是a,如果这是真的,我检查是否有一个空字段围绕它,这样你就可以连续4行
| | | A | a | a | | |
| a | a | A | | | | |
| | | A | a | | A | |
| | | A | | | A | A |
等等..我检查威胁的每一种可能性。在行之后,我为列和对角线
执行此操作你看到了更好的解决方案吗?
编辑2:
private Field row(int row, int column, int Player) {
Field field = null;
int j = 0;
boolean check = false;
if(column + 3 < board.getColumn()) {
for(int i = column; i< column + 4; i++) {
if(board.getValue(row, i).equals(Player)){
j++;
}
else if(board.getValue(row, i).equals(" ") && check == false) {
j++;
check = true;
field = new Field(row,i);
}
}
if(j == 4) {
return field;
}
}
return null;
}
我将从4个不同点调用该方法。你这个会起作用吗?
答案 0 :(得分:2)
为什么以一切神圣的名义,你有相同的血腥代码复制粘贴N次?唯一的区别是血腥数字会发生变化。在循环中重写它们,然后只有一个点来检查是否正确。
答案 1 :(得分:1)
如果您有不同的概念,我认为您的代码会更好很多,例如:
1,检查方向的方法:diagonalChecker(2x),verticalChecker,horizontalChecker。这些方法是在循环中检查来自一个方向的威胁(例如coulmn是x,row是
for(row = n; row<n+4; row++) {
...
}
2,如果您知道这些方法不会构成威胁,请暂停这些方法
3,从新硬币周围的不同起点调用这些方法。可能有一个循环。
+1 :也许您应该查看this解决方案并获得一些想法
如果您的解决方案更清晰,也会更容易发现错误。
更新到您的更新:我会做大致类似的事情(没有经过测试,只是为了这个想法):
对不同的玩家使用枚举会更好。
enum Player {
RED, BLUE
}
使rowCheck尽可能简单:
private boolean rowCheck(int row, int column, Player player) {
boolean isThreeOfTheSameInOneRow = true;
for (int i = column; i < column + 4; i++) {
if (!boundariesCheck(row, i) || !board.getValue(row, i).equals(player)) {
isThreeOfTheSameInOneRow = false;
break;
}
return isThreeOfTheSameInOneRow;
}
这样你就可以在一个地方检查边界。您可能希望将其拆分为2(列和行)。
private boolean boundariesCheck(int row, int column) {
boolean result = false;
if (0 < column && column < board.getColumn() && 0 < row && row < board.getRow()) {
result = true;
}
return result;
}
答案 2 :(得分:0)
你可以简化这些事情。主要是通过使用for
- 循环和一些执行边界检查的实用程序方法。
在更大的范围内:你在那里做的只是一个“真正的人工智能”的一小步。事实上,当你想为这么简单的棋盘游戏编写一个AI时,只有三件事是必须的:
这三种简单的方法已经允许您实现MiniMax算法(http://en.wikipedia.org/wiki/Minimax)。对于像“连接四”这样的简单游戏,即使是最简单的算法实现也很容易击败任何休闲玩家。 (并且......有“Connect Four”的认真的玩家吗?)。如果你想要更复杂的AI,它甚至可以扩展为使用Alpha-Beta-Pruning(http://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning)。
然而:您可能想要考虑结合检查玩家是否已经赢了,以及您在那里尝试的检查 - 即如果玩家能够获胜,如果他放置在特定位置。当你已经有一个方法来检查玩家是否赢了,你可以通过
检查玩家是否获胜这个实现粗略看起来像这样。 (不是为优雅或效率而优化,而是为了简单和希望直观......)
private boolean canWinByPlacingOn(String player, int r, int c)
{
if (board.getValue(r, c).equals(" "));
{
board.setValue(r, c, player);
boolean hasWon = hasWon(player);
board.setValue(r, c, " ");
if (hasWon)
{
return true;
}
}
return false;
}
private boolean hasWon(String player)
{
int maxR = board.getRow()-4;
int maxC = board.getColumn()-4;
for (int r=0; r<maxR; r++)
{
for (int c=0; c<maxC; c++)
{
if (startsLineAt(player, r, c, 1, 0))
{
return true;
}
if (startsLineAt(player, r, c, 0, 1))
{
return true;
}
if (startsLineAt(player, r, c, 1, 1))
{
return true;
}
}
}
return false;
}
private boolean startsLineAt(String player, int r, int c, int dr, int dc)
{
for (int i=0; i<4; i++)
{
String current = board.getValue(r, c);
if (!current.equals(player))
{
return false;
}
r += dr;
c += dc;
}
return true;
}