0% found this document useful (0 votes)
6 views7 pages

演示

This document contains a C program for a graphical chess game where a player competes against an AI. The game includes features such as initializing the game interface, handling player and AI moves, checking for victories, and saving game data to a file. The AI has multiple difficulty levels, ranging from random moves to strategic play based on the game state.

Uploaded by

yudadada111
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views7 pages

演示

This document contains a C program for a graphical chess game where a player competes against an AI. The game includes features such as initializing the game interface, handling player and AI moves, checking for victories, and saving game data to a file. The AI has multiple difficulty levels, ranging from random moves to strategic play based on the game state.

Uploaded by

yudadada111
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

#include <graphics.

h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <stdio.h>

#define BOARD_SIZE 20
#define CELL_SIZE 18

int ChessMap[BOARD_SIZE][BOARD_SIZE] = { 0 }; // 0: 空;1: 黑;2: 白(AI)


int flag = 0; // 0: 玩家回合;1: AI 回合
int game_status = 0; // 0: 进行中;1: 玩家胜;2: AI 胜;3: 平局
int difficulty = -1; // AI 难度,-1 表示未选择

// 初始化游戏界面
void initGame() {
initgraph(500, 360, SHOWCONSOLE);

IMAGE img;
loadimage(&img, "bk.jpg");
putimage(0, 0, &img);

setlinecolor(BLACK);
for (int i = 0; i <= BOARD_SIZE; i++) {
line(0, i * CELL_SIZE, 360, i * CELL_SIZE);
line(i * CELL_SIZE, 0, i * CELL_SIZE, 360);
}

setbkmode(TRANSPARENT);
settextcolor(WHITE);
outtextxy(380, 50, "玩家:黑棋");
outtextxy(380, 80, "AI :白棋");
}

// 判断胜利函数
int judge(int row, int col) {
int color = ChessMap[row][col];
if (color == 0) return 0;

// 横向检查
int count = 1;
for (int i = col + 1; i < BOARD_SIZE && ChessMap[row][i] == color; i++) {
count++;
}
for (int i = col - 1; i >= 0 && ChessMap[row][i] == color; i--) {
count++;
}
if (count >= 5) return color;

// 纵向检查
count = 1;
for (int i = row + 1; i < BOARD_SIZE && ChessMap[i][col] == color; i++) {
count++;
}
for (int i = row - 1; i >= 0 && ChessMap[i][col] == color; i--) {
count++;
}
if (count >= 5) return color;

// 左上 - 右下斜向检查
count = 1;
for (int i = 1; row + i < BOARD_SIZE && col + i < BOARD_SIZE && ChessMap[row +
i][col + i] == color; i++) {
count++;
}
for (int i = 1; row - i >= 0 && col - i >= 0 && ChessMap[row - i][col - i] ==
color; i++) {
count++;
}
if (count >= 5) return color;

// 右上 - 左下斜向检查
count = 1;
for (int i = 1; row - i >= 0 && col + i < BOARD_SIZE && ChessMap[row - i][col +
i] == color; i++) {
count++;
}
for (int i = 1; row + i < BOARD_SIZE && col - i >= 0 && ChessMap[row + i][col -
i] == color; i++) {
count++;
}
if (count >= 5) return color;

return 0;
}

// 评估某个位置的得分
int evaluate(int row, int col, int color) {
int score = 0;
int directions[4][2] = { {1, 0}, {0, 1}, {1, 1}, {1, -1} };

for (int d = 0; d < 4; d++) {


int dx = directions[d][0];
int dy = directions[d][1];
int count = 1;
int emptyCountLeft = 0;
int emptyCountRight = 0;

// 正向检查
for (int i = 1; row + i * dy < BOARD_SIZE && col + i * dx < BOARD_SIZE &&
col + i * dx >= 0; i++) {
if (ChessMap[row + i * dy][col + i * dx] == color) {
count++;
}
else if (ChessMap[row + i * dy][col + i * dx] == 0) {
emptyCountRight++;
break;
}
else {
break;
}
}

// 反向检查
for (int i = 1; row - i * dy >= 0 && col - i * dx < BOARD_SIZE && col - i *
dx >= 0; i++) {
if (ChessMap[row - i * dy][col - i * dx] == color) {
count++;
}
else if (ChessMap[row - i * dy][col - i * dx] == 0) {
emptyCountLeft++;
break;
}
else {
break;
}
}

// 根据连子数量和空位情况计算得分
if (count >= 5) {
score += 10000;
}
else if (count == 4) {
if (emptyCountLeft + emptyCountRight >= 1) {
score += 1000;
}
}
else if (count == 3) {
if (emptyCountLeft + emptyCountRight >= 2) {
score += 100;
}
}
else if (count == 2) {
if (emptyCountLeft + emptyCountRight >= 3) {
score += 10;
}
}
}

return score;
}

// AI 落子函数
void AI_Move(int difficulty, int* lastX, int* lastY) {
int x = 0, y = 0;

switch (difficulty) {
case 0: // 简单模式:随机落子
do {
x = rand() % BOARD_SIZE;
y = rand() % BOARD_SIZE;
} while (ChessMap[x][y] != 0);
break;

case 1: { // 中等模式:优先靠近现有棋子
int move_found = 0;
for (int dx = -1; dx <= 1 && !move_found; dx++) {
for (int dy = -1; dy <= 1 && !move_found; dy++) {
if (dx == 0 && dy == 0) continue;
for (int i = 1; i < 5; i++) {
int cx = 9 + dx * i;
int cy = 9 + dy * i;
if (cx < 0 || cx >= BOARD_SIZE || cy < 0 || cy >= BOARD_SIZE)
continue;
if (ChessMap[cx][cy] == 0) {
for (int ddx = -1; ddx <= 1; ddx++) {
for (int ddy = -1; ddy <= 1; ddy++) {
if (ddx == 0 && ddy == 0) continue;
int nx = cx + ddx;
int ny = cy + ddy;
if (nx >= 0 && nx < BOARD_SIZE && ny >= 0 && ny <
BOARD_SIZE && ChessMap[nx][ny] == 2) {
x = cx;
y = cy;
move_found = 1;
break;
}
}
if (move_found) break;
}
}
}
}
}
if (!move_found) {
do {
x = rand() % BOARD_SIZE;
y = rand() % BOARD_SIZE;
} while (ChessMap[x][y] != 0);
}
break;
}

case 2: { // 困难模式:优先堵截玩家连子或创造自己连子,考虑潜在连子
int best_score = -1;
int best_move_x = -1, best_move_y = -1;

for (int i = 0; i < BOARD_SIZE; i++) {


for (int j = 0; j < BOARD_SIZE; j++) {
if (ChessMap[i][j] == 0) {
// 评估自己落子的得分
ChessMap[i][j] = 2;
int score_self = evaluate(i, j, 2);
ChessMap[i][j] = 0;

// 评估阻止玩家落子的得分
ChessMap[i][j] = 1;
int score_opponent = evaluate(i, j, 1);
ChessMap[i][j] = 0;

int total_score = score_self * 2 + score_opponent; // 自己落子得分权重更


if (total_score > best_score) {


best_score = total_score;
best_move_x = i;
best_move_y = j;
}
}
}
}

x = best_move_x;
y = best_move_y;
break;
}

case 3: { // 地狱模式:考虑更长远的局势,更注重创造自己的连子和阻止玩家的连子
int best_score = -1;
int best_move_x = -1, best_move_y = -1;

for (int i = 0; i < BOARD_SIZE; i++) {


for (int j = 0; j < BOARD_SIZE; j++) {
if (ChessMap[i][j] == 0) {
// 评估自己落子的得分
ChessMap[i][j] = 2;
int score_self = evaluate(i, j, 2);

// 评估阻止玩家落子的得分
ChessMap[i][j] = 1;
int score_opponent = evaluate(i, j, 1);
ChessMap[i][j] = 0;

// 考虑更长远的局势,增加对自己连子的权重
int total_score = score_self * 3 + score_opponent * 2;

if (total_score > best_score) {


best_score = total_score;
best_move_x = i;
best_move_y = j;
}
}
}
}

x = best_move_x;
y = best_move_y;
break;
}
}

ChessMap[x][y] = 2;
setfillcolor(WHITE);
// 绘制棋子到格子中心
solidcircle(y * CELL_SIZE + CELL_SIZE / 2, x * CELL_SIZE + CELL_SIZE / 2, 7);

// 记录当前落子位置
*lastX = x;
*lastY = y;

// 保存数据到文件
FILE* fp = fopen("data.txt", "a");
if (fp != NULL) {
fprintf(fp, "AI Move: Row %d, Col %d\n", x, y);
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
fprintf(fp, "%d ", ChessMap[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
}

// 优化鼠标点击处理,确保落在格子中心附近
void handleMouseClick(MOUSEMSG msg) {
if (msg.uMsg == WM_LBUTTONDOWN) {
// 检查点击位置是否在棋盘范围内
if (msg.x >= 0 && msg.x < 360 && msg.y >= 0 && msg.y < 360) {
int centerX = (msg.x / CELL_SIZE) * CELL_SIZE + CELL_SIZE / 2;
int centerY = (msg.y / CELL_SIZE) * CELL_SIZE + CELL_SIZE / 2;
int dx = msg.x - centerX;
int dy = msg.y - centerY;
// 判断是否点击在格子中心附近
if (dx * dx + dy * dy <= (CELL_SIZE / 2) * (CELL_SIZE / 2)) {
int col = msg.x / CELL_SIZE;
int row = msg.y / CELL_SIZE;
if (col < 0 || col >= BOARD_SIZE || row < 0 || row >= BOARD_SIZE ||
ChessMap[row][col] != 0) return;

ChessMap[row][col] = 1;
setfillcolor(BLACK);
// 绘制棋子到格子中心
solidcircle(col * CELL_SIZE + CELL_SIZE / 2, row * CELL_SIZE +
CELL_SIZE / 2, 7);

// 保存数据到文件
FILE* fp = fopen("data.txt", "a");
if (fp != NULL) {
fprintf(fp, "Player Move: Row %d, Col %d\n", row, col);
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
fprintf(fp, "%d ", ChessMap[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}

// 只判断当前落子位置是否获胜
if (judge(row, col) == 1) {
HWND hwnd = GetHWnd();
MessageBox(hwnd, "玩家胜利!", "游戏结束", MB_OK);
closegraph();
exit(0);
}
flag++;
}
}
}
}

int main() {
srand((unsigned)time(NULL));
initGame();

HWND hwnd = GetHWnd();


while (difficulty == -1) {
printf("选择 AI 难度(简单:0 中等:1 困难:2 地狱:3):");
scanf("%d", &difficulty);
if (difficulty < 0 || difficulty > 3) {
MessageBox(hwnd, "无效难度!", "提示", MB_OK);
difficulty = -1;
}
}

// 提示选择好难度
printf("你已经选择好相应难度!\n");

// 保存初始难度信息到文件
FILE* fp = fopen("data.txt", "w");
if (fp != NULL) {
fprintf(fp, "AI Difficulty: %d\n", difficulty);
fclose(fp);
}

int lastX = -1, lastY = -1;


while (1) {
if (flag % 2 == 0) { // 玩家回合
MOUSEMSG msg = GetMouseMsg();
handleMouseClick(msg);
}
else { // AI 回合
AI_Move(difficulty, &lastX, &lastY);
flag++;

// 只判断当前 AI 落子位置是否获胜
if (lastX != -1 && lastY != -1) {
int win = judge(lastX, lastY);
if (win == 2) {
MessageBox(hwnd, "AI 胜利!", "游戏结束", MB_OK);
closegraph();
return 0;
}
}
}

// 检查平局
int is_full = 1;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (ChessMap[i][j] == 0) {
is_full = 0;
break;
}
}
if (!is_full) break;
}
if (is_full) {
MessageBox(hwnd, "平局!", "游戏结束", MB_OK);
closegraph();
return 0;
}
}

closegraph();
return 0;
}

You might also like