井字棋代码
package a; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Scanner; import java.util.Set; public class TT2 { private Scanner scan; Set set_all; // 所有位置 Set[] set_xo; // 双方已经落子的位置 int igo; //有走棋权一方的索引 Set[] set_win; //所有赢棋子力排列局面 int iAI; //让AI持哪一方 int last_step; // 最后一步走在哪里 public TT2() { scan = new Scanner(System.in); set_all = new HashSet(); for(int i=0; i<9; i++) set_all.add(i); set_xo = new Set[2]; set_xo[0] = new HashSet(); set_xo[1] = new HashSet(); igo = 0; int[][] tmp = {{0,1,2},{3,4,5},{6,7,8}, {0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}}; set_win = new Set[tmp.length]; for(int i=0; i<tmp.length; i++){ set_win[i] = new HashSet(); for(int j=0; j<tmp[i].length; j++) set_win[i].add(tmp[i][j]); } iAI = -1; // AI不参与 last_step = -1; // 还没有最后一步 } // >0 必赢 <0必输 =0 平局 private int tryAIgo() { if(set_all.size() == set_xo[0].size() + set_xo[1].size()) return 0;//0的一方和1的一方棋子容量相等了 Set t = new HashSet(); t.addAll(set_all);//初始化棋盘 t.removeAll(set_xo[0]);//去掉走棋的位置 t.removeAll(set_xo[1]);//去掉另一方走棋的位置 int rr = -1; //假设必输 for(Object k: t){ set_xo[igo].add(k); //试走 try{ if(test_finish()==igo) return 1; igo = (igo+1)%2; try{ int r = tryAIgo(); if(r<0) return 1; if(r==0) rr = 0; // 发现平局走法 } finally{ igo = (igo+1)%2; //回溯 } } finally{ set_xo[igo].remove(k); } } return rr; } // 机器走棋 private int getAIresult() { Set t = new HashSet(); t.addAll(set_all); t.removeAll(set_xo[0]); t.removeAll(set_xo[1]); List win = new ArrayList(); // 记录所有赢局招法 List tie = new ArrayList(); // 记录所有平局招法 for(Object k: t){ set_xo[igo].add(k); //试走 try{ if(test_finish()==igo){ win.add(k); continue; } igo = (igo+1)%2; try{ int r = tryAIgo(); if(r<0) win.add(k); if(r==0) tie.add(k); } finally{ igo = (igo+1)%2; //回溯 } } finally{ set_xo[igo].remove(k); } } if(win.size()>0) return (Integer)win.get((int)(Math.random() * win.size())); if(tie.size()>0) return (Integer)tie.get((int)(Math.random() * tie.size())); //虽然机器智能判负,但棋盘仍可走,可以随机走一步,期待对手失误。 return randomGo(); } private int randomGo() { if(set_all.size() == set_xo[0].size() + set_xo[1].size()) return -1; List t = new ArrayList(); t.addAll(set_all); t.removeAll(set_xo[0]); t.removeAll(set_xo[1]); return (Integer)t.get((int)(Math.random() * t.size())); } private void show() { for(int i=0; i<9; i++){ if(i%3==0) System.out.println(); char c = ‘.‘; if(set_xo[0].contains(i)) c = ‘x‘; if(set_xo[1].contains(i)) c = ‘o‘; if(i == last_step) c -= 32; System.out.print(c + " "); } System.out.println(); } private int getPlayerInput() { char c = ‘x‘; if(igo==1) c = ‘o‘; for(;;){ try{ System.out.print("请" + c + "方走棋:"); int n = (iAI==igo)? getAIresult() : Integer.parseInt(scan.nextLine()); if(n<0) return n; // 认输 if(set_all.contains(n)==false) throw new Exception(""); if(set_xo[0].contains(n) || set_xo[1].contains(n)) throw new Exception(""); return n; } catch(Exception e){ System.out.println("不正确的输入位置...."); } } } // 0,1:有胜负分出,2:全部下完没分胜负,平局,-1:尚无胜负,可以继续下 private int test_finish() { for(int i=0; i<set_win.length; i++){ if(set_xo[0].containsAll(set_win[i])) return 0; // x胜 if(set_xo[1].containsAll(set_win[i])) return 1; // o胜 } if(set_xo[0].size() + set_xo[1].size() == set_all.size()) return 2; //平局 return -1; //继续 } // 设置AI持有哪一方 public void setAI(int n) { if(n>1) return; iAI = n; } public void start() { for(;;){ show(); int r = test_finish(); //检测是否棋局应该结束 if(r==0) System.out.println("x方胜出!"); if(r==1) System.out.println("o方胜出!"); if(r==2) System.out.println("平局结束!"); if(r>=0) break; int pi = getPlayerInput(); if(pi<0){ char c = igo==0 ? ‘x‘ : ‘o‘; System.out.println(c + "方放弃!游戏结束!"); break; } set_xo[igo].add(pi); last_step = pi; igo = (igo+1)%2; } } private static void welcome() { System.out.println("----------------"); System.out.println("井字棋游戏 coded by gyhang"); System.out.println("九宫格用 0~8 的数字表示:"); System.out.println("0 1 2"); System.out.println("3 4 5"); System.out.println("6 7 8"); System.out.println("x方与o方轮流走棋,x方先走,连成一条直线的一方获胜。"); System.out.println("------------------------------------------------------"); } public static void main(String[] args) { welcome(); TT2 a = new TT2(); a.setAI(0); //机器先走 //a.setAI(1); //人先走 //a.setAI(-1); //机器不参与 a.start(); } }
---------------- 井字棋游戏 coded by gyhang 九宫格用 0~8 的数字表示: 0 1 2 3 4 5 6 7 8 x方与o方轮流走棋,x方先走,连成一条直线的一方获胜。 ------------------------------------------------------ . . . . . . . . . 请x方走棋: X . . . . . . . . 请o方走棋:4 x . . . O . . . . 请x方走棋: x . . . o X . . . 请o方走棋:1 x O . . o x . . . 请x方走棋: x o . . o x . X . 请o方走棋:8 x o . . o x . x O 请x方走棋: x o X . o x . x o 请o方走棋:3 x o x O o x . x o 请x方走棋: x o x o o x X x o 平局结束!
原文:http://blog.csdn.net/u011925500/article/details/20953223