吴昊品游戏核心算法 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 

posted on 2013-02-28 13:16  吴昊系列  阅读(431)  评论(0编辑  收藏  举报

导航