c语言-函数(2)-大型程序

来源:互联网 发布:电信宽带网络测速 编辑:程序博客网 时间:2024/06/18 12:01

编写一个游戏--就是我们玩的黑白棋~将一个棋子放在对手的棋子旁,使对手在对角线,水平线,垂直线上的棋子被自己的棋子所包围,这样对手的棋子就变成自己的棋子了。这游戏是和计算机对弈。

#include<stdio.h>#include<stdbool.h>#include<ctype.h>#include<string.h>const int SIZE = 6;const char comp_c = '@';const char player_c = 'O';void display(char board[][SIZE]);int valid_moves(char board[][SIZE], bool moves[][SIZE],char player);void make_move(char board[][SIZE],int row, int col, char player);void computer_move(char board[][SIZE], bool moves[][SIZE],char player);int get_score(char board[][SIZE], char player);int best_move(char board[][SIZE],bool moves[][SIZE],char player);


头文件不可少,并把两个棋子的符号初始化设定为@和O,每个函数都有它的作用,display显示棋盘,valid_moves函数判断是否下的子有效,make_move函数用来确定所放棋子的坐标,computer_move函数讲的是计算机自己下子的步骤,get_score函数是计算棋盘上特定位置的分数,最后best_move函数计算并返回玩家当前有效走法中的最佳走法的分数。当然最重要的还是下面的main函数了。。。

int main(){char board[SIZE][SIZE] ;bool moves[SIZE][SIZE] ;int row = 0;int col = 0;int no_of_games = 0;int no_of_moves = 0;int invalid_moves = 0;int comp_score = 0;int user_score = 0;char y = 0;int x = 0;char again = 0;bool next_player = true;printf("\n REVERSI\n\n");printf("You can go first on the first game, then we will take turns.\n");printf("You will be white - (%c)\n I will be black - (%c).\n", player_c,comp_c);printf("Select a square for your move by typing a digit for the row\n""and a letter for the column with np spaces between.\n");printf("\n Good luck!Press Enter to start.\n");scanf("%c", &again);for(row = 0; row < SIZE; row++)for(col = 0;col < SIZE;col++)board[row][col] = ' ';int mid = SIZE/2;board[mid - 1][mid - 1] = board[mid][mid] = player_c;board[mid - 1][mid] = board[mid][mid - 1] = comp_c;display(board);do{next_player = !next_player;no_of_moves = 4;for(row = 0; row < SIZE; row++)for(col = 0; col < SIZE; col++)board[row][col] = ' ';int mid = SIZE/2;board[mid - 1][mid - 1] = board[mid][mid] = player_c;board[mid - 1][mid] = board[mid][mid - 1] = comp_c;do{display(board);if(next_player = !next_player){if(valid_moves(board, moves,player_c)){for(;;){printf("Please enter your move(row column): ");scanf(" %d%c", &x, &y);y = tolower(y) - 'a';x--;if(x >=0 && y >=0 && x < SIZE && moves[x][y]){make_move(board, x, y, player_c);no_of_moves++;break;}elseprintf("Not a valid move, try again.\n");}}elseif(++invalid_moves < 2){printf("\n You have to pass,press return");scanf("%c", &again);}elseprintf("\n Neither of us can go, so the game is over.\n");}else{if(valid_moves(board,moves, '@')){invalid_moves = 0;computer_move(board,moves,'@');no_of_moves++;}else{if(++invalid_moves < 2)printf("\n I have to pass, you go\n");elseprintf("\n Neither of us can go, so the game is over.\n");}}}while(no_of_moves < SIZE * SIZE && invalid_moves < 2);display(board);comp_score = user_score = 0;for(row = 0; row < SIZE;row++)for(col = 0;col < SIZE; col++){comp_score += board[row][col] == comp_c;user_score += board[row][col] == player_c;}printf("The final score is : \n");printf("Computer %d\n User %d\n\n",comp_score,user_score);printf("Do you want to play again (y/n): ");scanf(" %c",&again);}while(tolower(again) == 'y');printf("\n Goodbye\n");return 0;}

游戏要玩的下去,必须要有循环语句,这里需要加入两个嵌套的do while循环:外面的循环初始化每一次游戏,里面的循环让玩家和计算机轮流下子。变量player确定轮到谁下子了。当player是false时,就该计算机下子了,当player是true是,就该玩家下子了。player最初设定为true,在do while循环中将player设置成!player,就可以使玩家和计算机轮流下子,为了确定下一个是玩家还是计算机,翻转变量player的值,在if语句中测试其结果,该结果会自动让玩家和计算机轮流下子。


变量no_of_moves中的计数器值到达棋盘上所有方格的总数SIZE*SIZE时,或者变量invalid_moves的值到达2时,游戏结束。每走一步,就将invalid_moves的值设置为0,每次某部走法无效时,就递增该值。因此,只要连续两子无效,invalid_moves的值就到达2,表示两个玩家都不能再下子了。游戏结束,输出最后的棋盘和结果,并提供继续游戏的选择。


将行号-1,列字母-a,将行号和列字母换成是索引值。调用tolower()函数,以保证y中输入的值是小写字母。必须调用包含头文件<ctype.h>。


如果找到一个有效的棋格,就调用函数make_move()在该棋格上放置一个适当的棋子。如果计算机下子是有效的,就调用computer_move()函数走这一步,并递增移动次数。


void_display()函数如下:

void display(char board[][SIZE]){char col_label = 'a';int col = 0;int row = 0;printf("\n");for(col = 0;col < SIZE; col++)printf(" %c", col_label + col);printf("\n");for(row = 0;row <SIZE;row++){printf(" +");for(col = 0; col < SIZE;col++)printf("---+");printf("\n%2d|",row + 1);for(col = 0;col < SIZE;col++)printf(" %c |", board[row][col]);printf("\n");}printf(" +");for(col = 0;col < SIZE;col++)printf("---+");printf("\n");}


接下来是valid_move函数

int valid_moves(char board [ ] [ SIZE ], bool moves [ ] [ SIZE ], char player){int rowdelta = 0;int coldelta = 0;int x = 0;int y = 0;int no_of_moves = 0;int row = 0;int col = 0;char opponent = (player == player_c) ? comp_c : player_c;for(row = 0; row < SIZE; row++)for(col = 0; col < SIZE; col++)moves[row][col] = false;for(row = 0; row < SIZE; row++)for(col = 0; col < SIZE; col++){if(board[row][col] != ' ')continue;for(rowdelta = -1;rowdelta <= 1; rowdelta++)for(coldelta = -1;coldelta <= 1; coldelta++){if(row + rowdelta < 0 || row + rowdelta >= SIZE ||col + coldelta < 0|| col + coldelta >= SIZE||(rowdelta == 0 && coldelta ==0))continue;if(board[row + rowdelta][col + coldelta] == opponent){x = row + rowdelta;y = col + coldelta;for(;;){x += rowdelta;y += coldelta;if(x < 0 || x >=SIZE || y < 0 || y >= SIZE)break;if(board[x][y] == ' ')break;if(board[x][y] == player){moves[row][col] = true;no_of_moves++;break;}}}}}return no_of_moves;}

make_move函数:

void make_move(char board [ ] [ SIZE ], int row, int col, char player){int rowdelta = 0;int coldelta = 0;int x = 0;int y = 0;char opponent = (player == player_c) ? comp_c : player_c;board[row][col] = player;for(rowdelta = -1; rowdelta <= 1;rowdelta++)for(coldelta = -1;coldelta <= 1; coldelta++){if(row + rowdelta < 0 || row + rowdelta >= SIZE ||col+coldelta < 0 || col +coldelta >=SIZE ||(rowdelta==0  && coldelta==0))continue;if(board[row + rowdelta][col + coldelta] == opponent){x = row + rowdelta;y = col + coldelta;for(;;){x += rowdelta;y += coldelta;if(x < 0 || x >= SIZE || y < 0 || y >=SIZE)break;if(board[x][y] == ' ')break;if(board[x][y] == player){while(board[x -= rowdelta][y -= coldelta] == opponent)board[x][y] = player;break;}}}}}

要一下子,必须在所选的棋格上放置一个适当的棋子,并将被当前这个玩家棋子为主的对手棋子翻转过来。现在如果找到一个对手的棋子,就在一个无限for循环中沿着该棋子所在方向上寻找自己的棋子。如果出了棋盘或找到的空的棋格,就跳出for循环,在外层循环中移动到所选棋格的下一个棋格上。如果找到一个自己的棋子,就将所有对手的棋子变成自己的棋子。


还需要有改进的地方,比如棋格太小,可以把宏定义在扩大一点。横行的字符分开的太紧,导致不好下子,再去专研一下原因。

下一次函数进阶!





0 0
原创粉丝点击