C語言實作五子棋
基本思路
1.五子棋需要棋盤并能夠記錄玩家落子情況,可以使用二維數來保存資料,
2.采用雙人對戰模式,
3.五子棋實作的主要難度是判斷是否構成五子連珠,采用以下方法:

在某一點落子時,判斷以該坐標為中心的八個方向,有無與所落子顏色相同的棋子,如果有則統計相同棋子數目,將相對方向的數目相加構成一組,如果哪一組有五或以上相同的棋子,這個方向就構成了五子連珠,
代碼實作
多檔案形式,整個程式包括一個頭檔案game.h,兩個源檔案game.c和main.c
1.game.h——宏定義和頭檔案包含以及函式宣告等
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<windows.h>
void Game();//函式宣告
#define ROW 21//棋盤大小
#define COL 21
#define PLAYER1 1
#define PLAYER2 2
#define NEXT 3
#define DRAW 4
//八個不同的方向
#define UP 10
#define RITHT_UP 11
#define RIGHT 12
#define RIGHT_DOWN 13
#define DOWN 14
#define LEFT_DOWN 15
#define LEFT 16
#define LEFT_UP 17
2.main.c——程式入口,游戲主選單,對Game函式呼叫
#include"game.h"
void Menu()
{
printf("+----------------------------------+\n");
printf("+ 1.Play 2.Exit +\n");
printf("+----------------------------------+\n");
}
int main()
{
int select = 0;
int quit = 0;
//游戲為死回圈模式,不選擇退出則一直進行
while (!quit){
Menu();
printf("Please select:\n");
scanf("%d", &select);
switch (select)
{
case 1:
Game();
break;
case 2:
quit = 1;
break;
default:
printf("Enter error!\n");
break;
}
}
printf("Bye-bye!\n");
system("pause");
return 0;
}
3.game.c——Game函式實作
#include"game.h"
//定義兩個全域變數存放落子坐標,這樣做的好處是不用將\
坐標作為引數傳入各個函式
int x = 0;
int y = 0;
static void ShowBoard(int ar[][COL], int row,int col)
{
system("cls");
printf(" ");
for (int i = 0; i < col; i++)
{
printf("%2d ",i);
}
printf("\n");
for (int i = 0; i < row; i++)
{
printf("%-2d", i);
for (int j = 0; j < col; j++)
{
//遍歷陣列,列印棋盤對應內容
if (ar[i][j] == 0){
printf(" .");
}
else if (ar[i][j] == PLAYER1){
printf(" O");
}
else if (ar[i][j] == PLAYER2){
printf(" X");
}
else{
printf("Bug");
}
}
printf("\n");
}
}
static void PlayerMove(int ar[][COL], int row, int col,int who)
{
while (1){
printf("Please enter your position Player %d<x,y>\n",who);
scanf("%d %d", &x, &y);
//判斷坐標合法性
if (x<0 || x>row - 1 || y<0 || y>row - 1){
printf("Ener error!\n");
continue;
}
if (ar[x][y] == 0){
ar[x][y] = who;
break;//輸入正確的坐標才能跳出回圈
}
else{
printf("This position is not empty.\n");
continue;
}
}
}
static int ChessCount(int ar[][COL],int direction)
{
int count = 0;
//避免影響落子坐標x和y的值,定義兩個新的變數存放
int x_ = x;
int y_ = y;
//#define UP 10
//#define RITHT_UP 11
//#define RIGHT 12
//#define RIGHT_DOWN 13
//#define DOWN 14
//#define LEFT_DOWN 15
//#define LEFT 16
//#define LEFT_UP 17
//狀態機(while死回圈+switch case)
while (1){
switch (direction){
case UP:
x_--;
break;
case RITHT_UP:
x_--, y_++;
break;
case RIGHT:
y_++;
break;
case RIGHT_DOWN:
x_++, y_++;
break;
case DOWN:
x_++;
break;
case LEFT_DOWN:
x_++, y_--;
break;
case LEFT:
y_--;
break;
case LEFT_UP:
x_--, y_--;
break;
default:
//BUG
break;
}
//先判斷坐標合法性
if (x_<0 || x_>ROW - 1 || y_<0 || y_>COL - 1){
break;
}
//周邊棋子相同時,count+1,再回圈\
直到棋子不相同或者到邊界位置
if (ar[x_][y_] == ar[x][y]){
count++;
}
else{
break;
}
}
return count;
}
static int Judge(int ar[][COL],int row,int col)
{
int count = 0;//相同棋子的個數
//縱向相同棋子個數
count = ChessCount(ar, UP) + ChessCount(ar, DOWN)+1;
if (count >= 5){
return ar[x][y];
}
//橫向相同棋子個數
count = ChessCount(ar, LEFT) + ChessCount(ar, RIGHT)+1;
if (count >= 5){
return ar[x][y];
}
//左上到右下方向
count = ChessCount(ar, LEFT_UP) + ChessCount(ar, RIGHT_DOWN)+1;
if (count >= 5){
return ar[x][y];
}
//左下到右上方向
count = ChessCount(ar, RITHT_UP) + ChessCount(ar, LEFT_DOWN)+1;
if (count >= 5){
return ar[x][y];
}
//程式執行到這里,則說明沒有五子連珠,只有平局或者繼續兩種情況
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (ar[i][j] != 0){
return NEXT;
}
}
}
return DRAW;
}
void Game()
{
int board[ROW][COL] = { 0 };//定義二維陣列存放落子資訊
int ret = 0;//存放Judge函式回傳之前
while (1){
ShowBoard(board, ROW, COL);//展示棋盤
PlayerMove(board, ROW, COL,PLAYER1);//玩家落子
ret = Judge(board,ROW,COL);//判斷結果
if (ret != NEXT){
//判斷結果不不為NEXT則跳出回圈
break;
}
ShowBoard(board, ROW, COL);
PlayerMove(board, ROW, COL,PLAYER2);
ret = Judge(board,ROW,COL);
if (ret != NEXT){
break;
}
}
//游戲結果
switch (ret){
case PLAYER1:
printf("Player1 win!\n");
break;
case PLAYER2:
printf("Player2 win!\n");
break;
case DRAW:
printf("Draw!\n");
break;
default:
printf("Bug!\n");
break;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300880.html
標籤:其他
上一篇:云服務環境配置
