吴昊品游戏核心算法 Round 11 —— 吴昊教你玩Tic-Tac-Toe(模拟) (HDOJ 3075)

 

 

 井字棋是神马?

 井字棋,大陆、台湾又称为井字游戏圈圈叉叉;另外也有打井游戏OX的称呼,香港多称井字过三关、过三关,是种纸笔游戏

 怎么玩?

 两个玩家,一个打圈(O),一个打叉(X),轮流在3乘3的格上打自己的符号,最先以横、直、斜连成一线则为胜。

 如果双方都下得正确无误,将得和局。

 这种游戏实际上是由第一位玩家所控制,第一位玩家是攻,第二位玩家是守。

 第一位玩家在角位行第一子的话赢面最大(见图一),第二位玩家若是在边,角位下子,第一位玩家就可以以两粒连线牵制着第二位玩家,然后制造“两头蛇”。(我这里不知道所谓的“两头蛇”是什么,不过,我觉得还是在中间走棋可以得到最大的势力)

 

  Tic-Tac-Toe之歌(还是个中国歌手哦!)

 在中国,居然有一位歌手写了一首歌,专门赞美Tic-Tac-Toe的。

 徐婕儿的一首歌,歌词如下:

   一加上一也许不等于二

 徐婕儿

在爱情里也许没有规则

OH~BANY

每当我想给你更多自由

却又害怕对你失去了掌握

太多 太少

谁能说 什么是对错

OH~谁都想

让爱情 UNDER CONTROL

但真的 到最后 谁赢过~WU

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 谁先谁后 谁爱谁的多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 比来比去 结果差不多

你加上我有太多的可能

爱情有时就像排列组合

OH~BABY

有时候因为爱你而快乐

有时候却因为爱你而困惑

是好 是谁能说

什么是 对错

OH~我只想 把爱情当作享受

不在乎 那最后 的结果~WU

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 谁先谁后 谁爱谁的多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 比来比去 结果差不多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 谁先谁后 谁爱谁的多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 比来比去 结果差不多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 谁先谁后 谁爱谁的多

爱情这游戏就像在玩TIC TAC TOE

个○ ×个× 比来比去 结果差不多

 

  好啦!我们先不要管策略,我们先将其模拟出来(Source:HDOJ 3075)。

  Input:分很多案例,每个案例一行,九个字符,代表一个(可能不完整)棋谱。

  Output:对于每一个谱子,输出该走棋是否合乎规则(实际上就是需要你来模拟一下棋谱咯)

 

 1  /*
 2     Highlights:
 3                (1)利用vict函数判断此时局面的胜负情况
 4                (2)通过调用check函数来判定这局棋是否符合规则
 5    */
 6  
 7  #include<iostream>
 8   using  namespace std;
 9  
10   // 定义一个棋盘,i和j分别是行和列的下标
11    char map[ 4][ 4];
12   int i,j;
13  
14   // 想要获胜,有四种情况,为行,列,以及两个对角线
15    bool vict( char c)
16  {
17     for( i= 0;i< 3;i++)      // 搜索每一行
18        for( j= 0;i< 3;j++)
19        {
20         if(map[i][j]!=c)
21              break;
22         if(j== 2return  1;
23         }
24     for( i= 0;i< 3;i++)   // 搜索每一列
25        for( j= 0;j< 3;j++)
26      {
27         if(map[j][i]!=c)
28           break;
29         if(j== 2)
30           return  1;
31      }
32     for( i= 0;i< 3;i++)   // 搜索左上到右下的对角线(反对角线)
33     {
34       if(map[i][i]!=c)
35         break;
36       if(i== 2)
37         return  1;
38    }
39     for( i= 0;i< 3;i++)   // 搜索右上到左下的对角线(正对角线)
40     {
41       if(map[i][ 2-i]!=c)
42         break;
43       if(i== 2)
44         return  1;
45    }
46     return  0;
47  }
48 
49   bool check()
50  {
51     // 记录O和X或者是没有走的点的数目
52      int no,nx,nf;
53    no=nx=nf= 0;
54     for( i= 0;i< 3;i++)
55       for( j= 0;j< 3;j++)
56      {
57         if(map[i][j]== ' O ') no++;
58         else  if(map[i][j]== ' X ') nx++;
59         else nf++;
60         if(nx<no || nx>no+ 1return  0; // 不符合停止条件,因为nx代表先手。
61          if(vict( ' O ') && nx>no)  return  0; // 当后手赢时,应该nx=no,否则先手又走了一步,vict()函数判定这局棋是否有输赢出现
62          // 当一局棋走完了(存在胜负平三种情况),或者还没有走完但是胜负出现了,则表示局面是符合规则的
63          if(!nf || vict( ' O ') || vict( ' X '))
64           return  1;
65      }
66     return  0;
67  }
68 
69   int main()
70  {
71     // e代表读入了end的第一个字符,程序退出
72      while(cin>>map[ 0][ 0] && map[ 0][ 0]!= ' e '// 判断第一个数据是不是符合继续输入的标准
73     {
74      cin>>map[ 0][ 1]>>map[ 0][ 2];  // 因为第一个判断了,所以这一行剩下的我就一个一个输入了(好原始的方法)。
75        for(i= 1;i< 3;i++)
76      {
77         for( j= 0;j< 3;j++)
78        {
79          cin>>map[i][j];
80           if(!check()) cout<< " in ";
81          cout<< " valid\n ";
82        }
83      }
84    }
85     return  0;
86  }
87 
88 

你可能感兴趣的:(round)