網站首頁 編程語言 正文
一、三子棋
三子棋小游戲的實現主要依賴于循環語句、函數和數組。
主要思路:設計棋盤、初始化棋盤、玩家下棋、電腦下棋及判斷輸贏。
判斷輸贏條件:當任一方連續三個棋子成一條直線,即為獲勝。
1.演示效果
2.完整代碼
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3//行
#define COL 3//列
void Init_board(char board[ROW][COL], int row, int col)//初始化棋盤
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void Print_board(char board[ROW][COL], int row, int col)//打印棋盤
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
void Player_board(char board[ROW][COL], int row, int col)//玩家下棋
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋>:");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐標已被占用,請重新輸入!\n");
}
}
else
{
printf("坐標非法,請重新輸入!\n");
}
}
}
void Computer_board(char board[ROW][COL], int row, int col)//電腦下棋
{
printf("電腦下棋>:\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int Is_full(char board[ROW][COL], int row, int col)//用來判斷是否還有空格
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char Is_win(char board[ROW][COL], int row, int col) //判斷輸贏
{
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 < col; 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[0][0] != ' ')//判斷對角線是否相等
{
return board[0][0];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] != ' ')//判斷對角線是否相等
{
return board[1][1];
}
if (1 == Is_full(board, row, col))//Is_full的返回值等于1,說明棋盤已經滿了,沒有空格了
return 'P';
return 'C';
}
void menu()
{
printf("*******************\n");
printf("*** 1.開始游戲 **\n");
printf("*** 0.結束游戲 **\n");
printf("*******************\n");
}
void game()
{
printf("**** 游戲開始 ***\n");
char ret = 0;
char board[ROW][COL] = { 0 };
Init_board(board, ROW, COL);
Print_board(board, ROW, COL);
while(1)
{
Player_board(board, ROW, COL);
Print_board(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
Computer_board(board, ROW, COL);
Print_board(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家贏!\n");
if (ret == '#')
printf("電腦贏!\n");
if (ret == 'P')
printf("平局!\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("請選擇>:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戲結束!\n");
break;
default:
printf("選擇項不存在,請重新選擇!\n");
break;
}
} while (input);
}
二、代碼解析
1.初始化棋盤
void Init_board(char board[ROW][COL], int row, int col)//初始化棋盤
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
剛開始定義的數組中初始值為0,但是打印的時候會發生錯誤,所以要先將數組中的值改為空格,以確保在打印棋盤的時候能夠得到想要的結果。
2.打印棋盤
void Print_board(char board[ROW][COL], int row, int col)//打印棋盤
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
打印出來為:
3.玩家下棋
void Player_board(char board[ROW][COL], int row, int col)//玩家下棋
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋>:");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐標已被占用,請重新輸入!\n");
}
}
else
{
printf("坐標非法,請重新輸入!\n");
}
}
}
玩家下棋要判斷輸入的下標是否符合要求,是否為空格,當輸入的坐標不在范圍內時,輸入坐標非法,重新輸入。當輸入的坐標不是空格,已被占用時也需要重新輸入,這里注意玩家輸入的坐標是從1開始的,并非從0。
4.電腦下棋
void Computer_board(char board[ROW][COL], int row, int col)//電腦下棋
{
printf("電腦下棋>:\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
電腦下棋時,需要用rand函數讓其產生在0 ~ row-1和0 ~ col-1之間,并且每次程序開始時產生的數都不相同,所以rand函數要和srand函數配合使用。具體使用方法可參考猜數字小游戲中游戲主題函數的介紹。
5.判斷輸贏
int Is_full(char board[ROW][COL], int row, int col)//判斷是否還有空格
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char Is_win(char board[ROW][COL], int row, int col) //判斷輸贏
{
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 < row; 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[0][0] != ' ')
{
return board[0][0];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] != ' ')
{
return board[1][1];
}
if (1 == Is_full(board, row, col))//Is_full的返回值等于1,說明棋盤已經滿了,沒有空格了
return 'P';
return 'C';
}
假設用P表示平局,用C表示游戲繼續,用*表示玩家獲勝,用#表示電腦獲勝,我們需要判斷行、列和對角線上是否有三個連續符號組成的直線,并且可以根據符號判斷出是誰贏誰輸。當沒有三個連續的符號組成的直線,且沒有空格時為平局。其中Is_full函數是用來判斷數組中是否還有空格。
6.游戲主體函數
通過調用具體的實現函數,完成界面的布局。
void game()
{
printf("**** 游戲開始 ***\n");
char ret = 0;
char board[ROW][COL] = { 0 };
Init_board(board, ROW, COL);
Print_board(board, ROW, COL);
while(1)
{
Player_board(board, ROW, COL);
Print_board(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
Computer_board(board, ROW, COL);
Print_board(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家贏!\n");
if (ret == '#')
printf("電腦贏!\n");
if (ret == 'P')
printf("平局!\n");
}
7.菜單函數
void menu()
{
printf("*******************\n");
printf("*** 1.開始游戲 **\n");
printf("*** 0.結束游戲 **\n");
printf("*******************\n");
}
8.頭文件及主函數
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3//行
#define COL 3//列
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("請選擇>:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戲結束!\n");
break;
default:
printf("選擇項不存在,請重新選擇!\n");
break;
}
} while (input);
}
原文鏈接:https://blog.csdn.net/weixin_53943591/article/details/127476902
相關推薦
- 2022-11-10 Kotlin?協程異步熱數據流的設計與使用講解_Android
- 2023-06-17 解讀C語言非void函數卻沒有return會怎么樣_C 語言
- 2022-08-16 C語言清楚了解指針的使用_C 語言
- 2022-03-24 C++內存管理介紹_C 語言
- 2022-11-26 Linux?top命令詳解_linux shell
- 2022-03-17 .NET?6開發TodoList應用實現系列背景_實用技巧
- 2023-04-22 python的open函數使用案例代碼_python
- 2022-06-13 docker從安裝入門到應用部署及私有倉庫搭建基礎命令_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支