失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言实现三子棋?五子棋?不 是n子棋

C语言实现三子棋?五子棋?不 是n子棋

时间:2023-05-02 06:58:23

相关推荐

C语言实现三子棋?五子棋?不 是n子棋

目录

前言

1、 game_tic.h

2、 test.c

3、game_tic.c

3.1 游戏主体

3.2 游戏的具体实现

3.2.1 打印棋盘

3.2.2 初始化棋盘

3.2.3 玩家进行下棋

3.2.4 电脑下棋

3.2.5 判断是否获胜

3.2.6 判断棋盘是否已经满

4、代码展示

4.1 game_tic.h

4.2 test.c

4.3 game_tic.c

5、一定要看这里

前言

实现这样一个代码程序,其实并不算太难,所需要的知识量概括为,数组函数循环语句分支语句。在这之中想必最为复杂的就是判断是否获胜了吧。

废话不多说,让我们开始吧。

1、 game_tic.h

game_tic.h : 自定义头文件,主要用于:

1 . 库函数的包含

2 . 自定义函数的申明

3 . 定义棋盘大小

#ifndef GAME_TIC_H#define GAME_TIC_H//棋盘大小#define ROW 15#define COL 15//方便计算用#define ROWS (ROW + 1)#define COLS (COL + 1)//防止用数组检索的时候,出现非法访问#define ROWSS (ROWS + 1)#define COLSS (COLS + 1)#define NUM 5// 确定n子棋//包含的头文件#include <stdio.h>#include <windows.h>#include <time.h>#include <stdlib.h>//函数声明void game_tic();void InitBoard(char board[ROWSS][COLSS]);void PrintBoard(char board[ROWSS][COLSS]);void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);char IsWin(char board[ROWSS][COLSS], int x, int y, char el);#endif

2、 test.c

test.c : 用于实现大致界面

#include "game_tic.h"void menu(){int input = 0;do{printf("********************************\n");printf("****** 0.返回 *******\n");printf("****** 1. n子棋游戏 *******\n");printf("****** 2.(还没想好)*******\n");printf("********************************\n");printf("请选择 >: ");scanf("%d", &input);switch (input){case 1:game_tic();break;default:system("cls");printf("输入错误,请从新输入\n");break;}} while (input);}void start()//选择开始菜单{int input = 0;do{printf("************************\n");printf("****** 1.开始游戏 ****\n");printf("****** 0.退出程序 ****\n");printf("************************\n");printf("请输入 >: ");scanf("%d", &input);if (input == 1){menu();}else if (input != 0){printf("输入错误,请从新输入\n");system("cls");//清屏}} while (input);}int main(){start();return 0;}

3、game_tic.c

game_tic.c : 用于实现游戏内容

3.1 游戏主体

因为数组在进行传参的时候传的是首元素地址,数组在使用其它函数的时候不会想形参一样进行销毁,所以我们可以引用一个数组来保存坐标。

注意

ComputMark[2] = { 0 }; 用于记录电脑坐标

PlayerMark[2] = { 0 }; 用于记录玩家坐标

此做法在本程序内起到关键作用

//游戏主体void game_tic(){srand((unsigned int)time(NULL));int x = 0;int y = 0;char board[ROWSS][COLSS] = { 0 };int ComputMark[2] = { 0 };//记录电脑的坐标int PlayerMark[2] = { 0 };//记录玩家的坐标InitBoard(board);PrintBoard(board);while (1){PlayerMove(board, PlayerMark, '*');PrintBoard(board);x = PlayerMark[0];y = PlayerMark[1];if ('*' == IsWin(board, x, y, '*')){printf("玩家获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}ComputerMove(board, ComputMark,'#');PrintBoard(board);x = ComputMark[0];y = ComputMark[1];if ('#' == IsWin(board, x, y, '#')){printf("电脑获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}}}

3.2 游戏的具体实现

3.2.1 打印棋盘

void PrintBoard(char board[ROWSS][COLSS]){int i = 0;int j = 0;system("cls");for (i = 1; i < ROWS; i++)//打印横坐标{printf("%4d", i);}printf("\n");for (i = 1; i < ROWS; i++){printf("%-2d", i);//打印列坐标for (j = 1; j < COLS; j++){printf(" %c ", board[i][j]);if(j != COLS - 1)printf("|");}printf("\n ");for (j = 1; j < COLS && i < ROWS - 1; j++){printf("----");}printf("\n");}}

效果图展示:

ROW 为 3,COL 为 3 的时候 (三子棋棋盘)

ROW 为 15,COL 为 15 的时候 (五子棋棋盘)

3.2.2 初始化棋盘

在每次进行游戏之前需要对棋盘进行初始化,即里面元素全放空格 。

void InitBoard(char board[ROWSS][COLSS]){int i = 0;int j = 0;for (i = 0; i < ROWSS; i++){for (j = 0; j < COLSS; j++){board[i][j] = ' ';}}}

3.2.3 玩家进行下棋

在接收到一个可用坐标时,将其记录在数组内

注意

如果想实现玩家 VS 玩家,可以将 电脑下棋 改为 玩家下棋

void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1){int x = 0;int y = 0;while (1){printf("请输入坐标 (x,y)");scanf("%d,%d", &x, &y);if (x > 0 && x < COLSS && y > 0 && y < ROWSS){if (board[y][x] == ' '){board[y][x] = p1;break;}else{printf("输入的坐标已被占用,请从新输入\n");}}else{printf("非法输入坐标,请从新输入\n");}}PlayerMark[0] = x;PlayerMark[1] = y;}

3.2.4 电脑下棋

电脑下棋的时候,我使用了 rand( ) 函数进行随机取值

如果想了解函数的用法请参考 :/reference/cstdlib/rand/?kw=rand

void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2){while (1){int x = rand() % COL + 1;int y = rand() % ROW + 1;computmark[0] = x;computmark[1] = y;if (board[y][x] == ' '){board[y][x] = p2;break;}}}

3.2.5 判断是否获胜

IsCount : 返回当前下棋坐标周围的棋子数量

char IsWin(char board[ROWSS][COLSS],int x, int y, char el){//继续 返回 'C'//获胜 返回 e1if (NUM == IsCount(board, x, y)){return el;}else{return 'C';}}

思路

落下一个棋子,记录它的坐标,然后向4个方向去寻找相同的棋子并记录数量,用一个数组去存储每个方向的棋子数量,取最大值返回

毕竟也不能保证不会出现这样的情况

//计数int IsCount(char board[ROWSS][COLSS], int x, int y){int i = 0;int moveX = x;int moveY = y;int count = 1;//计数int countmax = 0;//4个方向上的最多棋子数量int countarr[4] = { 0 };//记录 4 个方向上的棋子数量// [0] 为左上斜// [1] 为右上斜// [2] 为竖// [3] 为横//左上斜if (board[moveY + 1][moveX - 1] == board[moveY][moveX] || board[moveY - 1][moveX + 1] == board[moveY][moveX]){count = 1;//左上角for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}//右下角for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}countarr[0] = count;moveX = x;moveY = y;}//右上斜if (board[moveY - 1][moveX - 1] == board[moveY][moveX] || board[moveY + 1][moveX + 1] == board[moveY][moveX]){count = 1;for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX -= 1;moveY -= 1;}for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY += 1;}countarr[1] = count;moveX = x;moveY = y;}//竖if (board[moveY][moveX] == board[moveY + 1][moveX] || board[moveY][moveX] == board[moveY - 1][moveX]){count = 1;//向上计数for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&(board[moveY][moveX] == board[moveY + 1][moveX]); i++){count++;moveY += 1;}for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY - 1][moveX]); i++){count++;moveY -= 1;}countarr[2] = count;moveX = x;moveY = y;}//横if (board[moveY][moveX] == board[moveY][moveX + 1] || board[moveY][moveX] == board[moveY][moveX - 1]){count = 1;for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX + 1]); i++){count++;moveX += 1;}for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX - 1]); i++){count++;moveX -= 1;}countarr[3] = count;}countmax = arrmax(countarr);return countmax;}

//判断4个方向里的棋子数量的最大值int arrmax(int arr[4]){int i = 0;int max = arr[0];for (i = 1; i < 4; i++){if (arr[i] > max){max = arr[i];}}return max;}

3.2.6 判断棋盘是否已经满

若棋盘已满,还没有分出胜负,则退出游戏,按平局处理

int IsFull(char board[ROWSS][COLSS]){int i = 0;int j = 0;for (i = 1; i < ROWS; i++){for (j = 1; j < COLS; j++){if (board[i][j] == ' ')return 0;}}return 1;}

4、代码展示

4.1 game_tic.h

#ifndef GAME_TIC_H#define GAME_TIC_H//棋盘大小#define ROW 15#define COL 15#define ROWS (ROW + 1)#define COLS (COL + 1)#define ROWSS (ROWS + 1)#define COLSS (COLS + 1)#define NUM 5// 确定n子棋//包含的头文件#include <stdio.h>#include <windows.h>#include <time.h>#include <stdlib.h>//函数声明void game_tic();void InitBoard(char board[ROWSS][COLSS]);void PrintBoard(char board[ROWSS][COLSS]);void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);char IsWin(char board[ROWSS][COLSS], int x, int y, char el);#endif

4.2 test.c

#include "game_tic.h"void menu(){int input = 0;do{printf("********************************\n");printf("****** 0.返回 *******\n");printf("****** 1. n子棋游戏 *******\n");printf("****** 2.(还没想好)*******\n");printf("********************************\n");printf("请选择 >: ");scanf("%d", &input);switch (input){case 1:game_tic();break;default:system("cls");printf("输入错误,请从新输入\n");break;}} while (input);}void start()//选择开始菜单{int input = 0;do{printf("************************\n");printf("****** 1.开始游戏 ****\n");printf("****** 0.退出程序 ****\n");printf("************************\n");printf("请输入 >: ");scanf("%d", &input);if (input == 1){menu();}else if (input != 0){printf("输入错误,请从新输入\n");system("cls");//清屏}} while (input);}int main(){start();return 0;}

4.3 game_tic.c

#include "game_tic.h"//判断棋盘是否满int IsFull(char board[ROWSS][COLSS]){int i = 0;int j = 0;for (i = 1; i < ROWS; i++){for (j = 1; j < COLS; j++){if (board[i][j] == ' ')return 0;}}return 1;}int arrmax(int arr[4]){int i = 0;int max = arr[0];for (i = 1; i < 4; i++){if (arr[i] > max){max = arr[i];}}return max;}//计数int IsCount(char board[ROWSS][COLSS], int x, int y){int i = 0;int moveX = x;int moveY = y;int count = 1;//计数int countmax = 0;//4个方向上的最多棋子数量int countarr[4] = { 0 };//记录 4 个方向上的棋子数量// [0] 为左上斜// [1] 为右上斜// [2] 为竖// [3] 为横//左上斜if (board[moveY + 1][moveX - 1] == board[moveY][moveX] || board[moveY - 1][moveX + 1] == board[moveY][moveX]){count = 1;//左上角for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}//右下角for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}countarr[0] = count;moveX = x;moveY = y;}//右上斜if (board[moveY - 1][moveX - 1] == board[moveY][moveX] || board[moveY + 1][moveX + 1] == board[moveY][moveX]){count = 1;for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX -= 1;moveY -= 1;}for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY += 1;}countarr[1] = count;moveX = x;moveY = y;}//竖if (board[moveY][moveX] == board[moveY + 1][moveX] || board[moveY][moveX] == board[moveY - 1][moveX]){count = 1;//向上计数for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&(board[moveY][moveX] == board[moveY + 1][moveX]); i++){count++;moveY += 1;}for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY - 1][moveX]); i++){count++;moveY -= 1;}countarr[2] = count;moveX = x;moveY = y;}//横if (board[moveY][moveX] == board[moveY][moveX + 1] || board[moveY][moveX] == board[moveY][moveX - 1]){count = 1;for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX + 1]); i++){count++;moveX += 1;}for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX - 1]); i++){count++;moveX -= 1;}countarr[3] = count;}countmax = arrmax(countarr);return countmax;}char IsWin(char board[ROWSS][COLSS],int x, int y, char el){//继续 返回 'C'//获胜 返回 e1if (NUM == IsCount(board, x, y)){return el;}else{return 'C';}}//电脑 游玩void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2){while (1){int x = rand() % COL + 1;int y = rand() % ROW + 1;computmark[0] = x;computmark[1] = y;if (board[y][x] == ' '){board[y][x] = p2;break;}}}// 玩家 游玩void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1){int x = 0;int y = 0;while (1){printf("请输入坐标 (x,y)");scanf("%d,%d", &x, &y);if (x > 0 && x < COLSS && y > 0 && y < ROWSS){if (board[y][x] == ' '){board[y][x] = p1;break;}else{printf("输入的坐标已被占用,请从新输入\n");}}else{printf("非法输入坐标,请从新输入\n");}}PlayerMark[0] = x;PlayerMark[1] = y;}//初始化棋盘void InitBoard(char board[ROWSS][COLSS]){int i = 0;int j = 0;for (i = 0; i < ROWSS; i++){for (j = 0; j < COLSS; j++){board[i][j] = ' ';}}}//打印棋盘void PrintBoard(char board[ROWSS][COLSS]){int i = 0;int j = 0;system("cls");for (i = 1; i < ROWS; i++)//打印横坐标{printf("%4d", i);}printf("\n");for (i = 1; i < ROWS; i++){printf("%-2d", i);//打印列坐标for (j = 1; j < COLS; j++){printf(" %c ", board[i][j]);if(j != COLS - 1)printf("|");}printf("\n ");for (j = 1; j < COLS && i < ROWS - 1; j++){printf("----");}printf("\n");}}//游戏主体void game_tic(){srand((unsigned int)time(NULL));int x = 0;int y = 0;char board[ROWSS][COLSS] = { 0 };int ComputMark[2] = { 0 };int PlayerMark[2] = { 0 };InitBoard(board);PrintBoard(board);while (1){PlayerMove(board, PlayerMark, '*');PrintBoard(board);x = PlayerMark[0];y = PlayerMark[1];if ('*' == IsWin(board, x, y, '*')){printf("玩家获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}ComputerMove(board, ComputMark,'#');PrintBoard(board);x = ComputMark[0];y = ComputMark[1];if ('#' == IsWin(board, x, y, '#')){printf("电脑获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}}}

5、一定要看这里

既然你都看到这里了

如果对你右帮助或者觉得好的话,请给一个赞φ(゜▽゜*)♪

如果喜欢作者或者想看更多内容的话,请点一下关注(´▽`ʃ♡ƪ)

如果你怕找不到这篇博客,有一个放走丢的办法,看到那个星星了吗,点一下有惊喜哦

咱也不是是说特别想要,就是想请您可怜可怜这位卑微的博主吧

如果觉得《C语言实现三子棋?五子棋?不 是n子棋》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。