一.游戏介绍
三字棋又名井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),在程序中我们就不需要纸和笔,我们直接输入棋子坐标即可,然后由分别代表‘*’和‘#’的玩家和电脑轮流在格子里留下标记任意三个标记形成一条直线,则为获胜。
二.游戏实现思路
1.需要一个棋盘,用二维数组创建
char board[ROW][COL];//创建棋盘
2. 初始化棋盘,设计一个函数初始化棋盘
Initboard(board,ROW,COL);//初始化棋盘
3.打印棋盘,设计一个函数打印棋盘
Displayboard(board,ROW,COL);//打印棋盘
4.1.玩家下棋,玩家输入信息
4.2.电脑下棋,电脑自动输入信息
PlayerMove(board,ROW,COL);//玩家下棋
ComputerMove(board,ROW,COL);
5.判断棋局输赢情况
这里我们可以去思考,我们可以设计一个函数去判断,首先我们知道,玩家下棋是‘*’,电脑下棋是‘#’,就可以让函数返回‘*’,‘#’分别代表玩家赢和电脑赢,除此之外,我们还应该考虑两种情况,平局和游戏继续,这里就设计返回‘Q’,‘C’来表示平局和游戏继续
三.游戏实现的详细代码
main.c文件:
1. #include "game.h" 2. void menu() 3. { 4. printf("******************************\n"); 5. printf("* 1.play *\n"); 6. printf("* 0.exit *\n"); 7. printf("******************************\n"); 8. 9. } 10. void game() 11. { 12. char count={0}; 13. char board[ROW][COL];//创建棋盘 14. Initboard(board,ROW,COL);//初始化棋盘 15. Displayboard(board,ROW,COL);//打印棋盘 16. while(1)//循环是为了一直下棋,直到一方赢或着棋盘满了 17. { 18. PlayerMove(board,ROW,COL);//玩家下棋 19. Displayboard(board,ROW,COL); 20. count=Iswin(board,ROW,COL);//判断棋局情况 21. if(count!='C')//如果返回的是‘C’则棋盘还有空余且没有一方胜出 22. { 23. break; 24. } 25. ComputerMove(board,ROW,COL); 26. Displayboard(board,ROW,COL); 27. count=Iswin(board,ROW,COL); 28. if(count!='C') 29. { 30. break; 31. } 32. } 33. if(count=='*')//如果返回的是‘*’则是玩家赢 34. { 35. printf("玩家赢\n"); 36. } 37. else if(count=='#')//如果返回的是‘#’则是电脑赢 38. { 39. printf("电脑赢\n"); 40. } 41. if(count=='Q')//如果返回的是‘Q’则是平局 42. { 43. printf("平局\n"); 44. } 45. } 46. int main() 47. { 48. srand((unsigned int)time(NULL));//控制随机变量更加自然 49. int input=0; 50. do 51. { 52. menu();//菜单 53. printf("请选择\n"); 54. scanf("%d",&input); 55. switch(input) 56. { 57. case 1: 58. game(); 59. break; 60. case 0: 61. printf("退出游戏\n"); 62. break; 63. default: 64. printf("输入非法,重新选择\n"); 65. break; 66. } 67. }while(input); 68. return 0; 69. }
game.c文件:
1. #include "game.h" 2. void Initboard(char board[ROW][COL],int row,int col) 3. { 4. int i=0,j=0; 5. for(i=0;i<row;i++) 6. { 7. for(j=0;j<col;j++) 8. { 9. board[i][j]=' ';//三字棋,一共9个格子,将这9个格子初始化为空格‘ ’ 10. } 11. } 12. } 13. void Displayboard(char board[ROW][COL],int row,int col) 14. { 15. printf("*************三字棋*****************\n"); 16. int i=0,j=0; 17. for(i=0;i<row;i++) 18. { 19. for(j=0;j<col;j++) 20. { 21. printf(" %c ",board[i][j]); 22. if(j<col-1) 23. { 24. printf("|"); 25. } 26. } 27. printf("\n"); 28. if(i<row-1) 29. { 30. for(j=0;j<col;j++) 31. { 32. printf("---"); 33. if(j<col-1) 34. { 35. printf("|"); 36. } 37. } 38. printf("\n"); 39. } 40. } 41. printf("*************三字棋*****************\n"); 42. } 43. void PlayerMove(char board[ROW][COL],int row,int col) 44. { 45. printf("玩家下棋:>\n"); 46. int x=0,y=0; 47. while(1) 48. { 49. printf("输入下棋坐标\n"); 50. scanf("%d %d",&x,&y); 51. if(x>=1&&x<=row&&y>=1&&y<=col) 52. { 53. if(board[x-1][y-1]==' ') 54. { 55. board[x-1][y-1]='*'; 56. break; 57. } 58. else 59. { 60. printf("该坐标被占用,请重新输入\n"); 61. } 62. } 63. else 64. { 65. printf("输入不合法,重新输入\n"); 66. } 67. } 68. } 69. void ComputerMove(char board[ROW][COL],int row,int col) 70. { 71. printf("电脑下棋:>\n"); 72. int x=0,y=0; 73. while(1) 74. { 75. x=rand()%row; 76. y=rand()%col; 77. if(board[x][y]==' ') 78. { 79. board[x][y]='#'; 80. break; 81. } 82. } 83. } 84. int Judge(char board[ROW][COL],int row,int col)//判断是否有空余 85. { 86. int i=0,j=0; 87. for(i=0;i<row;i++) 88. { 89. for(j=0;j<col;j++) 90. { 91. if(board[i][j]==' ') 92. { 93. return 1; 94. } 95. } 96. } 97. return -1; 98. } 99. char Iswin(char board[ROW][COL],int row,int col) 100. { 101. int i=0; 102. for(i=0;i<row;i++) 103. { 104. if(board[i][0]==board[i][1]&&board[i][1]==board[i][2]&&board[i][1]!=' ')//判断行是否相等 105. { 106. return board[i][1]; 107. } 108. } 109. for(i=0;i<row;i++) 110. { 111. if(board[0][i]==board[1][i]&&board[1][i]==board[2][i]&&board[1][i]!=' ')//判断列是否相等 112. { 113. return board[1][i]; 114. } 115. } 116. if(board[0][0]==board[1][1]&&board[1][1]==board[2][2]&&board[1][1]!=' ')//判断对角线是否相等 117. { 118. return board[1][1]; 119. } 120. if(board[0][2]==board[1][1]&&board[1][1]==board[2][0]&&board[1][1]!=' ')//判断对角线是否相等 121. { 122. return board[1][1]; 123. } 124. int ret=Judge(board,row,col);//判断棋盘是否有空余 125. if(ret==1)//有空余就返回‘C’ 126. { 127. return 'C'; 128. } 129. else 130. { 131. return 'Q';//没有空余就返回‘Q’平局 132. } 133. }
game.h文件:
1. #ifndef game_h 2. #define game_h 3. #endif 4. 5. //头文件 6. #include <stdio.h> 7. #include<stdlib.h>//控制随机变量的头文件 8. #include<time.h>//控制随机变量的头文件 9. 10. //定义行列长度,这里是三字棋,应该定义为3 11. #define ROW 3 12. #define COL 3 13. 14. void Initboard(char board[ROW][COL],int row,int col);//初始化 15. void Displayboard(char board[ROW][COL],int row,int col);//打印棋盘 16. void PlayerMove(char board[ROW][COL],int row,int col);//玩家下棋 17. void ComputerMove(char board[ROW][COL],int row,int col);//电脑下棋 18. char Iswin(char board[ROW][COL],int row,int col);//判断棋局情况
四.游戏成功运行的结果
注:我使用的编译器是xcode(mac版本的)
五. 游戏细节补充
大家可以设置一个用户登陆过程,即是输入正确的密码才能进入游戏,让我们来看看
1. int main() 2. { 3. int count=0; 4. char arr[]="bit.is.good999"; 5. char brr[20]={0}; 6. while(count<3) 7. { 8. printf("请输入密码:>\n"); 9. scanf("%s",brr); 10. if(strcmp(arr,brr)==0) 11. { 12. printf("密码输入正确,正在加载游戏\n"); 13. srand((unsigned int)time(NULL));//控制随机变量更加自然 14. int input=0; 15. do 16. { 17. menu();//菜单 18. printf("请选择\n"); 19. scanf("%d",&input); 20. switch(input) 21. { 22. case 1: 23. game(); 24. break; 25. case 0: 26. printf("退出游戏\n"); 27. break; 28. default: 29. printf("输入非法,重新选择\n"); 30. break; 31. } 32. }while(input); 33. if(input==0) 34. { 35. break; 36. } 37. } 38. else 39. { 40. printf("密码输入错误,错误三次将退出登陆--------%d次\n",count+1); 41. count++; 42. } 43. } 44. return 0; 45. }
运行结果:其实这个用户登录过程,可以广范适用于其他的游戏,大家可以去尝试一下
注: 使用字符串比较函数时strcmp,不要忘记引头文件#include<string.h>
六.心得
这个三字棋看似生活不起眼的小游戏,但是对于像我一样才开始接触C的人来说,实现起来也不是那样轻而易举。实现三字棋的过程,让我明白掌握代码并非最重要的,最重要的是,理清实现功能的逻辑,例如:实现这个游戏时,首先得了解游戏规则,其次需要一个棋盘......只要自己逻辑清晰,写代码也是水到渠成,还有一点,只要自己掌握逻辑,下次想再次实现这个功能或着分析已写的代码就不会犯怵了。最后我们要多善于整理总结,下次我们遇到类似的问题,就可以触类旁通了。