前言
🥰想必各位大佬们上学的时候都玩过这种游戏吧,摊牌了我也玩过,巧了我还是在高中上课的时候偷偷玩的,当然不出意外就要出一点小小意外了,当时被老师逮了个正着,现在还能想起来那年夏天语文课上的画面。当然现在我们也要去玩三子棋,咱们今天自己现造一个程序来玩这个游戏。当然这个程序要有一定的C语言基础,其实里面也都是一些基本的一句没有指针、结构体等等这些高难度的知识点,好,各位小客官们坐稳扶好了要发车了。😍😍
三子棋简介
🍔《三子棋》是一款古老的民间传统游戏,又被称为黑白棋、圈圈叉叉棋、井字棋、一条龙、九宫棋等。游戏分为双方对战(这里我们设计的是人机对战),双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子连成一条线的一方则视为胜利者,下面我们来详细介绍一下《三子棋》相关的玩法规则🥝
棋盘介绍
🍪棋盘呈横三行列,纵三列分布,为九宫格样式。因为棋盘结构简单,所以在没有制式棋盘时,我们甚至可以随手拿笔画一个简易棋盘来进行游戏,而这最大的好处就是随便找个地方就可以玩这个简单而有趣的游戏了。
规则介绍
🍁双方手持若干数量(一般是4-5)的棋子,因为如果棋子摆满棋盘,先手方摆放的棋子数量为5,后手方摆放棋子数量为4。
⭕双方轮流在格子里摆放棋子,先连成三棋一线者视为胜利;
⭕棋盘被摆满棋子仍未分出胜利,视为平局。
程序设计
基本流程
在写三子棋的代码之前,我们来看看实现这个游戏的逻辑:
1.菜单界面选择开始或者退出游戏。
2.创建棋盘并初始化。
3.打印棋盘。
4.玩家落子(玩家输入行列坐标的方式来落子),'*’表示玩家落子。
5.判定胜负关系(输,赢,和棋),'Q’表示和棋。
6.电脑落子(随机位置落子) ,'#’表示电脑落子。
7.判定胜负关系。
8.回到 步骤2 继续执行。
菜单界面打印
void menu() { printf("*********************************\n"); printf("******1.play 0.exit *******\n"); printf("*********************************\n"); }
🔴1表示开始玩游戏
🔴0表示退出游戏
创建棋盘并初始化
棋盘:使用3行3列的二维数组来表示,元素类型是char。
使用宏定义的原因
⭕推高代码可读性,后续代码中遇到3,方便理解含义。
⭕提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便。
#define ROW 3 #define LEN 3 void DesplayBoard(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { board[i][j] = ' ';//表示棋盘上的空白区域 } } }
打印棋盘
void PrintBoard(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { printf(" %c ", board[i][j]); if (j < len - 1) printf("|"); } printf("\n"); if (i < row - 1) { for (int j = 0; j < len; j++) { printf("---"); if (j < len - 1) printf("|"); } } printf("\n"); } }
玩家落子
玩家输入行列坐标表示落子,使用’ * ’表示玩家落子。
✅1.玩家落子需要在棋盘范围内。
✅2.玩家要在棋盘上空的地方落子。
✅3.如果输入的坐标不满足要重新输入。
//玩家下棋 void PlayerMove(char board[ROW][LEN], int row, int len) { while (true) { int x, y = 0; printf("请输入你想要落子的位置->"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= len) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else printf("已经被占用,请重新输入:\n"); } else { printf("输入错误,请重新输入\n"); } } printf("----玩家 *----\n"); }
电脑落子
电脑随机产生行列坐标,'o’表示电脑落子。
注意:
1.要在主函数中使用srand((unsigned int)time(0))详细可见:这是随机数生成详细的介绍
将时间作为随机数种子,确保得到的行列坐标是真随机。
2.要在棋盘上空的地方下棋。
void ComputerBoard(char board[ROW][LEN], int row, int len) { while (true) { int x = rand() % row; int y = rand() % len; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } printf("----电脑 #----\n"); }
判断胜负
🍁此处约定返回结果的含义:
💧‘*’ 表示玩家获胜
💧‘#’ 表示电脑获胜
💧’ C’ 表示胜负未分
💧 ‘Q’ 表示和棋
1.判定是否和棋
(1)调用isFull函数。
(2)如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。
(3)如果棋盘满了未分出胜负,和棋。
2.判定胜负
(1)判定所有的行
(2)判定所有的列
(3)判定两条对角线
//判断输赢 玩家赢--> * 电脑赢--> # 平局--> Q 继续--> C bool IsFull(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { if (board[i][j] == ' ') return false; } } return true; } char IsWin(char board[ROW][LEN], int row, int len) { int i = 0; for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') { return board[i][0]; } } for (i = 0; i < len; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') { return board[0][i]; } } if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') || (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')) { return board[1][1]; } //判断是否平局 if (IsFull(board, row, len)) { return 'Q'; } //继续游戏 return 'C'; }
代码总汇
✅Game.h 头文件
#pragma once #include<stdio.h> #include<stdbool.h> #include <time.h> #include <stdlib.h> #define ROW 3 #define LEN 3 void DesplayBoard(char board[ROW][LEN], int row, int len); void PrintBoard(char board[ROW][LEN], int row, int len); //玩家下棋 void PlayerMove(char board[ROW][LEN], int row, int len); //电脑下棋 void ComputerBoard(char board[ROW][LEN], int row, int len); //判断输赢 玩家赢--> * 电脑赢--> # 平局--> Q 继续--> C char IsWin(char board[ROW][LEN], int row, int len);
✅Game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"Game.h" void DesplayBoard(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { board[i][j] = ' '; } } } void PrintBoard(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { printf(" %c ", board[i][j]); if (j < len - 1) printf("|"); } printf("\n"); if (i < row - 1) { for (int j = 0; j < len; j++) { printf("---"); if (j < len - 1) printf("|"); } } printf("\n"); } } //玩家下棋 void PlayerMove(char board[ROW][LEN], int row, int len) { while (true) { int x, y = 0; printf("请输入你想要落子的位置->"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= len) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else printf("已经被占用,请重新输入:\n"); } else { printf("输入错误,请重新输入\n"); } } printf("----玩家 *----\n"); } //电脑下棋 void ComputerBoard(char board[ROW][LEN], int row, int len) { while (true) { int x = rand() % row; int y = rand() % len; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } printf("----电脑 #----\n"); } //判断输赢 玩家赢--> * 电脑赢--> # 平局--> Q 继续--> C bool IsFull(char board[ROW][LEN], int row, int len) { for (int i = 0; i < row; i++) { for (int j = 0; j < len; j++) { if (board[i][j] == ' ') return false; } } return true; } char IsWin(char board[ROW][LEN], int row, int len) { int i = 0; for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') { return board[i][0]; } } for (i = 0; i < len; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') { return board[0][i]; } } if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') || (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')) { return board[1][1]; } //判断是否平局 if (IsFull(board, row, len)) { return 'Q'; } //继续游戏 return 'C'; }
✅Test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"Game.h" void menu() { printf("*********************************\n"); printf("******1.play 0.exit *******\n"); printf("*********************************\n"); } void game() { char board[ROW][LEN] = { 0 }; DesplayBoard(board, ROW, LEN); char ret = 0; while (true) { PlayerMove(board, ROW, LEN); PrintBoard(board, ROW, LEN); ret = IsWin(board, ROW, LEN); if (ret != 'C') { break; } ComputerBoard(board, ROW, LEN); PrintBoard(board, ROW, LEN); ret = IsWin(board, ROW, LEN); if (ret != 'C') { break; } } if ('*' == ret) { printf("玩家赢\n"); } else if ('#' == ret) { printf("电脑赢\n"); } else if ('Q' == ret) { printf("平局\n"); } } int main() { srand(time(0)); int input = 0; do { menu(); printf("请选择--->>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误重,新选择\n"); break; } } while (input); return 0; }