三子棋
- ·功能介紹
- ·代碼實作及注釋
- 1、主函式的實作以及三子棋的構思框架(test.c)
- 2、三子棋功能的實作(game.c)
- 3、頭檔案的參考(game.h)
- ·代碼展示
·功能介紹
三子棋的基本功能有,電腦下棋,玩家落點是否合法,以及判贏機制,
·代碼實作及注釋
1、主函式的實作以及三子棋的構思框架(test.c)
簡單的一個選擇選單,玩家選完選項后,用switch陳述句分支,
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int main() {
srand((unsigned)time(NULL));
int a;
do
{
menu();
printf("請選擇選項\n");
scanf("%d", &a);
switch (a)
{
case 1:
game();
break;
case 2:
printf("游戲結束\n");
break;
default:
break;
}
} while (a != 2);
return 0;
}
其次在main函式中,有menu()函式,和game()函式,其中menu函式就是選單的輸出界面,比較簡單,如下:

void menu() {
printf("---------------------------------\n");
printf("*********************************\n");
printf("**********1、開始游戲************\n");
printf("**********2、退出游戲************\n");
printf("*********************************\n");
printf("---------------------------------\n");
}
2、三子棋功能的實作(game.c)
而game()函式則是游戲的主體,各個功能的實作都是在這個函式中實作,
注意:我們用二維陣列來實作棋盤,row和rol分別表示行和列,玩家棋子:‘X’, 電腦棋子:‘O’,
首先,第一個功能是重置棋盤initBoard();因為每一輪新的游戲都得是一個清空的棋盤,這個函式的主要功能就是在游戲開始前將我們的棋盤進行初始化,初始化的結果就是,每一個陣列都被重置為" "(空格),
void initBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
Showboard();重置完棋盤之后,就需要把棋盤列印出來了,因為玩家需要看到棋盤的樣子再決定下一步該怎么走,
void ShowBoard(char board[ROW][COL], int row, int col)
{
printf("=====================\n");
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
//三個空格
printf(" %c ", board[i][j]);
//兩列豎線
if (j < col - 1)
{
printf("|");
}
}
//換行
printf("\n");
//橫線只有2行
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
//
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
printf("=====================\n");
}

Playertime();玩家回合,玩家通過輸入坐標落子,但是需要判斷落子的位置是否合法、是否已經被其他棋子占用,
void ShowBoard(char board[ROW][COL], int row, int col)
{
printf("=====================\n");
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
//三個空格
printf(" %c ", board[i][j]);
//兩列豎線
if (j < col - 1)
{
printf("|");
}
}
//換行
printf("\n");
//橫線只有2行
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
//
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
printf("=====================\n");
}
Computertime();
在玩家下完棋后,電腦隨機選定一個坐標落子,坐標在[row] [col]范圍內通過rand()函式隨機選定,
void Computertime(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row;
int y = rand() % col;;
if (board[x][y] == ' ')
{
board[x][y] = 'O';
break;
}
}
}

IsWin/isFull();判斷結果函式,每一次玩家或電腦落子之后,都需要判斷是否滿足獲勝條件或者平局條件,
獲勝的條件就是有任意一種棋子滿足了某一行或這某一列,以及正副對角線全部占滿,在判定某一行時,行數是不變的,所以我們只需要一個for回圈,遍歷所有的行數就可以判定,判定某一列同理,判斷正副對角線也不難,只需要指定坐標下的棋子一樣就滿足條件,滿足了條件之后,通過回傳’X’和’O‘來區分玩家獲勝還是電腦獲勝,
然后就是判斷棋盤是否還有空間下,那么只要有“ ”(空格)的陣列,就有空間可以下,如果沒有空間,回傳一個特定值,在main的game()函式中,依據不同的回傳值,來確定游戲結果,
static int isFull(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return -1;
}
}
}
return 1;
}
char IsWin(char board[ROW][COL], int row, int col)
{
//行
for (int i = 0; i < row; i++) {
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ') {
return board[i][0];
}
}
//列
for (int j = 0; j < col; j++) {
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') {
return board[0][j];
}
}
//正對角線、副對角線
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') {
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') {
return board[1][1];
}
//是否是平局
if (isFull(board, row, col) == 1)
{
return 'Q';
}
return ' ';
}


3、頭檔案的參考(game.h)
·頭檔案中,我們需要定義所有的頭檔案以及參考的各種函式,這邊添加了相關的注釋方便大家觀看,
·其中的define定義了行和列的大小
#pragma once
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void initBoard(char board[ROW][COL], int row, int col);
void ShowBoard(char board[ROW][COL], int row, int col);
void Playertime(char board[ROW][COL], int row, int col);
void Computertime(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
·代碼展示
game.h
#pragma once
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void initBoard(char board[ROW][COL], int row, int col);
void ShowBoard(char board[ROW][COL], int row, int col);
void Playertime(char board[ROW][COL], int row, int col);
void Computertime(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void initBoard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void ShowBoard(char board[ROW][COL], int row, int col)
{
printf("=====================\n");
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
//三個空格
printf(" %c ", board[i][j]);
//兩列豎線
if (j < col - 1)
{
printf("|");
}
}
//換行
printf("\n");
//橫線只有2行
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
//
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
printf("=====================\n");
}
void Playertime(char board[ROW][COL], int row, int col)
{
while (1)
{
printf("請輸入坐標");
int x = 0, y = 0;
scanf("%d%d", &x, &y);
if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
{
if (board[x - 1][y - 1] == ' ') {
board[x - 1][y - 1] = 'X';
break;
}
else
{
printf("坐標已經有棋子,請重新輸入,");
}
}
else
{
printf("坐標不合法");
}
}
}
void Computertime(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row;
int y = rand() % col;;
if (board[x][y] == ' ')
{
board[x][y] = 'O';
break;
}
}
}
static int isFull(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return -1;
}
}
}
return 1;
}
char IsWin(char board[ROW][COL], int row, int col)
{
//行
for (int i = 0; i < row; i++) {
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ') {
return board[i][0];
}
}
//列
for (int j = 0; j < col; j++) {
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' ') {
return board[0][j];
}
}
//正對角線、副對角線
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') {
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') {
return board[1][1];
}
//是否是平局
if (isFull(board, row, col) == 1)
{
return 'Q';
}
return ' ';
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu() {
printf("---------------------------------\n");
printf("*********************************\n");
printf("**********1、開始游戲************\n");
printf("**********2、退出游戲************\n");
printf("*********************************\n");
printf("---------------------------------\n");
}
void game() {
printf("開始玩游戲\n");
char board[ROW][COL] = { 0 };
initBoard(board, ROW, COL);
ShowBoard(board, ROW, COL);
char ret;
while (1)
{
Playertime(board, ROW, COL);
//每走完一步都要判斷一次結果
ret = IsWin(board, ROW, COL);
if (ret != ' ')
{
break;
}
ShowBoard(board, ROW, COL);
Computertime(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != ' ')
{
break;
}
ShowBoard(board, ROW, COL);
}
if (ret == 'X')
{
printf("玩家獲勝\n");
}
else if (ret == 'O')
{
printf("電腦獲勝\n");
}
else if (ret == 'Q')
{
printf("平局\n");
}
}
int main() {
srand((unsigned)time(NULL));
int a;
do
{
menu();
printf("請選擇選項\n");
scanf("%d", &a);
switch (a)
{
case 1:
game();
break;
case 2:
printf("游戲結束\n");
break;
default:
break;
}
} while (a != 2);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286702.html
標籤:其他
上一篇:JS實作簡單的坦克坦克移動及換向
