标签:inpu computer bre 棋盘 二维 ini 开始 == 简单的
今天要完成一个相对于之前学习更有挑战性的小程序——三子棋。
相信我们大部分人都接触过三子棋,这是一款操作简单易上手的小游戏。
先简单介绍一下三子棋的规则,方便我们接下来的编程和理解。规则如下:
在九宫格棋盘上,只要将自己的三个棋子走成一条线(横、竖、对角线),对方就算输了。
规则很简单,但是我们应该从哪里入手完成这个三子棋程序呢?
首先,我们的游戏程序应该先有个菜单页面,这个菜单页面用来让用户操作选择玩游戏,或是退出。
界面可以很简单,只需要几条 printf 语句即可。
这里我们尽可能用函数来完成游戏的功能:
void menu() { printf("***************************************\n"); printf("* 1.play 0.exit *\n"); printf("***************************************\n"); }
这就是一个简单的主菜单界面,效果如下:
既然菜单中有选项,我们就必须要设计一个变量用来接收用户的选择。
而且游戏程序本身应该允许用户反复进行玩耍,所以在主函数中,我们需要用一个循环来完成这个功能。
do-while循环在调用时会先运行循环体,而后在进行判断,所以这里我们选择使用do-while循环:
int main() { int choice; do { menu(); printf("Input your choice:"); scanf("%d", &choice); switch (choice) { case 1: game(); break; case 0: break; default: printf(" Input error!Please try again.\n"); break; } } while (choice); return 0; }
由于用户选择选项1时我们需要为用户启动游戏程序,所以这里我们使用一个switch语句来接受用户的选择。
选择0时退出程序,所以我们只需要跳出循环,即可退出。
而输入0、1之外的值时,我们应该向用户报输入错误,所以在default中输出一条报错信息。
接下来就是我们程序的重点——三子棋游戏本身了。
先创建一个game()函数,里面的内容我们一步步来填充。
void game() { }
在程序开始阶段,我们首先要创建一个3*3的二维字符数组,
由于长和宽我们要经常用到,为了后续修改方便,我们采用宏定义方式:
#define ROWS 3 #define COLS 3
接下来在game()函数中创建数组:
char board[ROWS][COLS];
并将这个数组进行初始化,因为这个数组在后续需要输出展示在用户面前,所以我们将值初始化为空格“ ”。
初始化用函数进行完成:
void init_board(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ‘ ‘; } } }
接下来,我们应该输出这个数组棋盘,来检查一下是否初始化完成,
但我们没有展示棋盘的函数,所以我们需要完成这个显示棋盘函数:
void show_board(char board[ROWS][COLS], int rows, int cols) { int i; for (int i = 0; i < rows; i++) { printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]); if (i != rows - 1) printf(" ---|---|--- \n"); } }
这里需要利用循环来输出我们棋盘的格式,格式不统一,可以根据自己的喜好进行修改。
下面展示一下我这个代码所输出的棋盘:
上面已经看出我的棋盘初始化已经完成,所以接下来我们需要考虑如何让电脑或用户进行下棋操作了。
电脑走需要让电脑产生随机坐标,然后在数组的这个坐标位置放入一个“X”作为电脑的棋子。
所以代码如下:
void ComputerMove(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Compter‘s turn to move:\n"); while (1) { x = rand() % rows; y = rand() % cols; if (board[x][y] == ‘ ‘) { board[x][y] = ‘X‘; break; } } }
rand()是用来生成随机数的,这里我们还需要在主函数main中加上一行代码。
由于我们不希望他多次生成随机数,生成一次就足够用了,所以直接在创建choice变量的下一行加上下面这个代码即可:
srand((unsigned int)time(NULL));
注意生成随机数需要引用time.h这个头文件。
电脑下完棋后,需要轮到我们的用户进行下棋操作,这个函数和电脑下棋大同小异,
但是要注意人的习惯不会输入(0,0)这个坐标,而是输入(1,1)。
所以这里我们要给传过去的参数-1。
解决这个问题后的代码如下:
void player_move(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Player‘s turn to move:\n"); while (1) { printf("Input x and y(like x y):\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= rows && y >= 1 && y <= cols) { if (board[x - 1][y - 1] == ‘ ‘) { board[x - 1][y - 1] = ‘O‘; break; } else printf("The location has been taken!Please try again.\n"); } else printf(" Input error!Please try again.\n"); } }
在双方走完后,我们需要判断是否胜利,也就是判断之前我们提到的规则,
这时我们需要编写一个checkwin()函数来检测并返回一个值表示谁获胜。
代码如下:
char check_win(char board[ROWS][COLS], int rows, int cols) { int i; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ‘ ‘) return board[i][1]; } for (i = 0; i < cols; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ‘ ‘) return board[1][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ‘ ‘) return board[1][1]; else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ‘ ‘) return board[1][1]; else if (is_full(board, rows, cols)) return ‘q‘; return 0; }
由于可能出现棋盘下满,却没人获胜的情况,
所以我们需要在其中判断一下平局的情况,
这里我们编写了一个is_full()函数,用来判断棋盘是否下满:
static int is_full(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { if (board[i][j] == ‘ ‘) return 0; } } return 1; }
注意这个函数我们只在checkwin中会使用到,我们并不希望它在其他源文件的函数中被使用,所以我们加上了static。
这时程序的雏形已经基本完成,我们只需要按我们自己理解的游戏步骤来完成game()函数即可。
所以完成后的game()函数如下所示:
void game() { char win = 0; char arr[ROWS][COLS]; init_board(board, ROWS, COLS); do { computer_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = check_win(board, ROWS, COLS); if (win != 0) break; player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = check_win(board, ROWS, COLS); } while (win == 0); if (win == ‘X‘) printf("You lose!Good luck next time!\n"); if (win == ‘O‘) printf("You win!Congratulations!\n"); if (win == ‘q‘) printf("The score was tied!Good luck next time!\n"); }
这样,将上面各个部分合在一起,这个程序就被我们完成了。
下面放上我自己写的,比较丑陋的代码:
我的代码分为三部分,
第一部分是头文件:
#ifndef __CHESS_H__ #define __CHESS_H__ #include<stdio.h> #include<time.h> #include<Windows.h> #define ROWS 3 #define COLS 3 void show_board(char board[ROWS][COLS], int rows, int cols); void init_board(char board[ROWS][COLS], int rows, int cols); void computer_move(char board[ROWS][COLS], int rows, int cols); void player_move(char board[ROWS][COLS], int rows, int cols); char check_win(char board[ROWS][COLS], int rows, int cols); # endif//__CHESS_H__
第二部分是源文件的函数部分:
#include"3chess.h" void show_board(char board[ROWS][COLS], int rows, int cols) { int i; for (int i = 0; i < rows; i++) { printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]); if (i != rows - 1) printf(" ---|---|--- \n"); } } void init_board(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ‘ ‘; } } } void computer_move(char board[ROWS][COLS], int rows, int cols) { int x, y, i; printf("Compter‘s turn to move:\n"); while (1) { x = rand() % rows; y = rand() % cols; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][0] == ‘X‘ && board[i][2] == ‘ ‘) { board[i][2] = ‘X‘; goto flag1; } else if (board[i][1] == board[i][2] && board[i][1] == ‘X‘ && board[i][0] == ‘ ‘) { board[i][0] = ‘X‘; goto flag1; } else if (board[i][0] == board[i][2] && board[i][2] == ‘X‘ && board[i][1] == ‘ ‘) { board[i][1] = ‘X‘; goto flag1; } else if (board[0][i] == board[1][i] && board[0][i] == ‘X‘ && board[2][i] == ‘ ‘) { board[2][i] = ‘X‘; goto flag1; } else if (board[1][i] == board[2][i] && board[1][i] == ‘X‘ && board[0][i] == ‘ ‘) { board[0][i] = ‘X‘; goto flag1; } else if (board[0][i] == board[2][i] && board[2][i] == ‘X‘ && board[1][i] == ‘ ‘) { board[1][i] = ‘X‘; goto flag1; } else if (board[0][0] == board[1][1] && board[0][0] == ‘X‘ && board[2][2] == ‘ ‘) { board[2][2] = ‘X‘; goto flag1; } else if (board[1][1] == board[2][2] && board[1][1] == ‘X‘ && board[0][0] == ‘ ‘) { board[0][0] = ‘X‘; goto flag1; } else if (board[0][0] == board[2][2] && board[0][0] == ‘X‘ && board[1][1] == ‘ ‘) { board[1][1] = ‘X‘; goto flag1; } else if (board[0][2] == board[1][1] && board[1][1] == ‘X‘ && board[2][0] == ‘ ‘) { board[2][0] = ‘X‘; goto flag1; } else if (board[1][1] == board[2][0] && board[1][1] == ‘X‘ && board[0][2] == ‘ ‘) { board[0][2] = ‘X‘; goto flag1; } else if (board[2][0] == board[0][2] && board[2][0] == ‘X‘ && board[1][1] == ‘ ‘) { board[1][1] = ‘X‘; goto flag1; } } for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][0] == ‘O‘ && board[i][2] == ‘ ‘) { board[i][2] = ‘X‘; goto flag1; } else if (board[i][1] == board[i][2] && board[i][1] == ‘O‘ && board[i][0] == ‘ ‘) { board[i][0] = ‘X‘; goto flag1; } else if (board[i][0] == board[i][2] && board[i][2] == ‘O‘ && board[i][1] == ‘ ‘) { board[i][1] = ‘X‘; goto flag1; } else if (board[0][i] == board[1][i] && board[0][i] == ‘O‘ && board[2][i] == ‘ ‘) { board[2][i] = ‘X‘; goto flag1; } else if (board[1][i] == board[2][i] && board[1][i] == ‘O‘ && board[0][i] == ‘ ‘) { board[0][i] = ‘X‘; goto flag1; } else if (board[0][i] == board[2][i] && board[2][i] == ‘O‘ && board[1][i] == ‘ ‘) { board[1][i] = ‘X‘; goto flag1; } else if (board[0][0] == board[1][1] && board[0][0] == ‘O‘ && board[2][2] == ‘ ‘) { board[2][2] = ‘X‘; goto flag1; } else if (board[1][1] == board[2][2] && board[1][1] == ‘O‘ && board[0][0] == ‘ ‘) { board[0][0] = ‘X‘; goto flag1; } else if (board[0][0] == board[2][2] && board[0][0] == ‘O‘ && board[1][1] == ‘ ‘) { board[1][1] = ‘X‘; goto flag1; } else if (board[0][2] == board[1][1] && board[1][1] == ‘O‘ && board[2][0] == ‘ ‘) { board[2][0] = ‘X‘; goto flag1; } else if (board[1][1] == board[2][0] && board[1][1] == ‘O‘ && board[0][2] == ‘ ‘) { board[0][2] = ‘X‘; goto flag1; } else if (board[2][0] == board[0][2] && board[2][0] == ‘O‘ && board[1][1] == ‘ ‘) { board[1][1] = ‘X‘; goto flag1; } } if (board[x][y] == ‘ ‘) { board[x][y] = ‘X‘; goto flag1; } } flag1:; } void player_move(char board[ROWS][COLS], int rows, int cols) { int x, y; printf("Player‘s turn to move:\n"); while (1) { printf("Input x and y(like x y):\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= rows && y >= 1 && y <= cols) { if (board[x - 1][y - 1] == ‘ ‘) { board[x - 1][y - 1] = ‘O‘; break; } else printf("The location has been taken!Please try again.\n"); } else printf(" Input error!Please try again.\n"); } } static int is_full(char board[ROWS][COLS], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { if (board[i][j] == ‘ ‘) return 0; } } return 1; } char check_win(char board[ROWS][COLS], int rows, int cols) { int i; for (i = 0; i < rows; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ‘ ‘) return board[i][1]; } for (i = 0; i < cols; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ‘ ‘) return board[1][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ‘ ‘) return board[1][1]; else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ‘ ‘) return board[1][1]; else if (is_full(board, rows, cols)) return ‘q‘; return 0; }
这一部分是经过发挥的,让电脑更智能,但代码部分我并没有想出简化的写法,只好一步步的用if语句进行完成了。
第三部分是源文件的游戏测试部分:
#include"3chess.h" void menu() { printf("***************************************\n"); printf("* 1.play 0.exit *\n"); printf("***************************************\n"); } void first_move() { printf("***************************************\n"); printf("* 1.computer first 2.player first *\n"); printf("***************************************\n"); } void game() { int choice_1, win; char board[ROWS][COLS]; init_board(board, ROWS, COLS); first_move(); flag: printf("Input your choice;"); scanf("%d", &choice_1); switch (choice_1) { case 1: do { computer_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = check_win(board, ROWS, COLS); if (win != 0) break; player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = check_win(board, ROWS, COLS); } while (win == 0); if (win == ‘X‘) printf("You lose!Good luck next time!\n"); if (win == ‘O‘) printf("You win!Congratulations!\n"); if (win == ‘q‘) printf("The score was tied!Good luck next time!\n"); break; case 2: do { show_board(board, ROWS, COLS); player_move(board, ROWS, COLS); show_board(board, ROWS, COLS); win = check_win(board, ROWS, COLS); if (win != 0) break; computer_move(board, ROWS, COLS); win = check_win(board, ROWS, COLS); } while (win == 0); if (win == ‘X‘) printf("You lose!Good luck next time!\n"); if (win == ‘O‘) printf("You win!Congratulations!\n"); if (win == ‘q‘) printf("The score was tied!Good luck next time!\n"); break; default: printf(" Input error!Please try again.\n"); goto flag; } } int main() { int choice; srand((unsigned int)time(NULL)); do { menu(); printf("Input your choice:"); scanf("%d", &choice); switch (choice) { case 1: game(); break; case 0: break; default: printf(" Input error!Please try again.\n"); break; } } while (choice); return 0; }
这一部分,我加入了让用户选择电脑先走或者用户先走的功能,使用户的游戏体验更好。
以上就是我的代码,希望各位能帮助我进行优化改进。
标签:inpu computer bre 棋盘 二维 ini 开始 == 简单的
原文地址:http://www.cnblogs.com/xiefei777/p/7710856.html