基于C语言实现五子棋游戏完整实例代码

本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解。

五子棋游戏代码如下:

/*
 * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序
 */
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>
#include <graphics.h>
#include<malloc.h>
/*
 * 对应键盘键的十六进制数字
 */
#define ESC 0x11b
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define BLANK 0x3920

#define PLAYER1 1
#define PLAYER2 2
#define COMPUTER 2
#define LENGTH 15
#define SEARCH_DEEP 2
/*
 * 用来在函数can_expand()查找可以扩展的节点步长
 */
#define STEP 1

/************全局变量定义***************/
int       x1 = 240,
        y1 = 240,
        oldx = 240,
        oldy = 240;
int       key_mode;
int       key_net;
int       step_sum = 0;
int       chessman[LENGTH][LENGTH];
int       depth = 2; /* 搜索的深度 */
int       a = 0,
        b = 0;
int       flag_run;
int       win_flag = 0;

typedef struct five_chess *point;
struct five_chess {
  int       x;
  int       y;
  int       layer;
  double     value;
  double     score;
  int       chess[LENGTH][LENGTH];
  int       record[LENGTH][LENGTH];
} A;

int       stack_deep0 = 0;
point      stack_c[10];
point      close[600];

void
push(point s0)
{
  if (stack_deep0 < 10)
 stack_c[stack_deep0++] = s0;
}

point
top()
{
  if (stack_deep0 > 0)
 return stack_c[stack_deep0 - 1];
  /*else return 一个什么样的东西?*/
}

void
pop()
{
  if (stack_deep0 > 0)
 stack_deep0--;
}

int
is_empty()
{
  if (stack_deep0 != 0)
 return 1;
  else
 return 0;
}

/************函数的声明**************/
void      five();
void      show();
int       win_or_not(int x0, int y0, int who,
   int chessman[LENGTH][LENGTH], int a);
void      set_chessman();
void      print_result();
/************评价函数部分************/
double     score_row(int i, int j, int chessman[LENGTH][LENGTH]);
double     score_col(int i, int j, int chessman[LENGTH][LENGTH]);
double     score_diag_45(int i, int j, int chessman[LENGTH][LENGTH]);
double     score_diag_135(int i, int j, int chessman[LENGTH][LENGTH]);
double     total_score(int who_running, int chessman[LENGTH][LENGTH]);
double     score(int chessman[LENGTH][LENGTH]);
int       rowdt(int i, int j, int chessman[LENGTH][LENGTH]);
int       coldt(int i, int j, int chessman[LENGTH][LENGTH]);
int       diadt(int i, int j, int chessman[LENGTH][LENGTH]);
int       vdiadt(int i, int j, int chessman[LENGTH][LENGTH]);
int       can_expand(int i, int j, int chessman[LENGTH][LENGTH]);
void     copy(point s1, point s0);

int
POW(int s, int t)
{
  int       sum = s,
          i;
  if (t <= 0)
 return 1;
  for (i = 0; i < t; i++)
 sum *= sum;
  return sum;

}

/*
 * 定义computer先手
 */
point
expand(point s0)
{
  int       flag;
  int       i,
          j;
  point      new_chess = (point) malloc(sizeof(struct five_chess));
/*************************这里出错***********************************/
  for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++)
   new_chess->chess[i][j] = s0->chess[i][j];

  for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++)
   new_chess->record[i][j] = s0->chess[i][j];

/*************************这里出错***********************************/
  if (s0->layer % 2 == 0)
 flag = COMPUTER;
  else
 flag = PLAYER1;

  for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++) {

   if (s0->record[i][j])             /*如果有棋子*/
 continue;
   if (can_expand(i, j, s0->chess) == 0)  /*如果有棋子,而且沿水平,树直,左上—右下,右上—左下,四个方向可以扩展*/
 continue;
   s0->record[i][j] = flag;
   new_chess->chess[i][j] = flag;
   new_chess->layer = s0->layer + 1;
   new_chess->x = i;
   new_chess->y = j;
   new_chess->record[i][j] = flag;
   return new_chess;
 }
  /*
   * for(i=5;i<10;i++) for(j=5;j<10;j++){ if(s0->record[i][j]) continue;
   * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
   * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag;
   * new_chess->layer=s0->layer+1; new_chess->chess[i][j]=flag ; return
   * new_chess; } for(i=2;i<12;i++) for(j=2;j<12;j++){
   * if(i>4&&i<10&&j>4&&j<10) continue; if(s0->record[i][j]) continue;
   * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
   * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag;
   * new_chess->layer=s0->layer+1; new_chess->chess[i][j]=flag; return
   * new_chess;
   *
   * } for(i=0;i<LENGTH;i++) for(j=0;j<LENGTH;j++){
   * if(i>1&&i<12&&j>1&&j<12) continue; if(s0->record[i][j]) continue;
   * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
   * new_chess->chess[i][j]=flag; new_chess->layer=s0->layer+1;
   * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag; return
   * new_chess; }
   */
  new_chess->layer = -1;
  return new_chess;
}

void
computer()
{
  int       i,
          j,
          k,
          num = 0;
  int       break_now = 0;
  int       break_then = 0;
  int       go_on = 0;
  point     s0 = NULL,
          s1 = NULL,
          s2 = NULL,
          max_chess = NULL;
  point     temps = NULL,
          s01;
  /*
   * 堆栈的初始化
   */
  stack_deep0 = 0;
  s0 = malloc(sizeof(struct five_chess));
  for (i = 0; i < 600; i++)              /*为什么是600*/
 close[i] = NULL;                 /*close是一个point 数组*/
  close[num++] = s0;
  for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++) {
   s0->chess[i][j] = chessman[i][j];
   s0->record[i][j] = chessman[i][j];
 }
  s0->layer = 0;
  s0->value = -3000000;
  s0->score = -3000000;
  push(s0);
  while (is_empty() != 0) {        /*看是栈否为空*/
 s01 = top();                  /*如果不是空*/
 s1 = expand(s01);             /*从栈顶开始展开*/
 close[num++] = s1;
 if (s1->layer == -1) {
   pop();
   continue;
 }
 go_on =
   win_or_not((s1->x + 1) * 30, (s1->y + 1) * 30, 2, s1->chess,
     1);
 if (go_on == 2) {
   a = (s1->x + 1) * 30;
   b = (s1->y + 1) * 30;
   break_then = 1;
   break;
 }
 go_on =
   win_or_not((s1->x + 1) * 30, (s1->y + 1) * 30, 1, s1->chess,
     1);
 if (go_on == 1) {
   a = (s1->x + 1) * 30;
   b = (s1->y + 1) * 30;
   break_then = 1;
   break;
 }
 s1->value = 30000;
 push(s1);
 while (1) {
   s1 = top();
   s2 = expand(s1);
   if (s2->layer == -1) {
 pop();
 if (s1->value > top()->value) {
   top()->value = s1->value;
   max_chess = s1;
 }
 free(s2);
 break;
   }/*end of if*/
   s2->score = score(s2->chess);
   temps = top();
   if (s2->score < temps->value)
 temps->value = s2->score;
   free(s2);
 }/*end of whiile(1) */
  }
  if (break_then == 0) {
 for (i = 0; i < LENGTH; i++) {
   for (j = 0; j < LENGTH; j++)
 if (max_chess->chess[i][j] != chessman[i][j]) {
   a = i * 30 + 30;
   b = j * 30 + 30;
   break_now = 1;
   break;
 }
   if (break_now == 1)
 break;
 }
  }
  for (i = 0; i < 600; i++) {
 if (close[i] == NULL)
   continue;
 free(close[i]);
  }

}

/**********************************************************/
void
main()
{
  int       key;
  int       play_with_who = 1;

  printf("1.Play with human\n2.Play with computer\nPlease choice: ");
  scanf("%d", &play_with_who);

  five();              /*显示棋盘*/
  show();

  if (play_with_who == 1) {   /*人与人玩*/
 while (1) {  /*设置人与人玩的界面*/
   settextstyle(0, 0, 2);
   if ((step_sum + 1) % 2) {
 setcolor(1);
 outtextxy(500, 180, "Player2");
 setcolor(4);
 outtextxy(500, 180, "Player1");
   } else {
 setcolor(1);
 outtextxy(500, 180, "Player1");
 setcolor(10);
 outtextxy(500, 180, "Player2");
   }

   if (bioskey(1))
 /*
  * 按了一次键盘那么就true,执行下面代码,这是bios。h
  */
   {
 key = bioskey(0);
 /*
  * 返回一个键盘值,如没有按键,则一直等待
  */
 switch (key) {
 case ESC:
   exit(0);
 case LEFT:
   if (x1 > 30) {
  x1 -= 30;
  show();   /*显示方框*/
   }
   break;
 case UP:
   if (y1 > 30) {
  y1 -= 30;
  show();
   }
   break;
 case RIGHT:
   if (x1 < 450) {
  x1 += 30;
  show();
   }
   break;
 case DOWN:
   if (y1 < 450) {
  y1 += 30;
  show();
   }
   break;
 case BLANK:         /*按下空格键后放置棋子*/
   {
  if (chessman[x1 / 30][y1 / 30])
    break;       /*如果当前位置有棋子,不能放置,退出*/
  step_sum++;    /*如果没有棋子,下一步谁走加1*/
  /*
  * P1 设置棋子
  */
  if (step_sum % 2) {
    setcolor(15);  /*画棋子*/
    setfillstyle(SOLID_FILL, 15); /* 封闭图形,进行实体填充*/
    circle(x1, y1, 10);      /*画圆*/
    floodfill(x1, y1, 15);    /*填充圆*/
    chessman[x1 / 30][y1 / 30] = PLAYER1;        /*设置棋盘状态*/
    win_flag = win_or_not(x1, y1, 1, chessman, 0);   /*分析游戏是否结束,谁胜谁败*/
    if (win_flag == 1)
  outtextxy(480, 240, "P1 Win");
    else if (win_flag == 3)
  outtextxy(480, 240, "DOGFALL");
    if (win_flag != 0) {           /*如果没人胜,游戏继续*/
  while (bioskey(1) == 0);
  closegraph();            /*what this mean?*/
    }
  } else { /* P2 设置棋子 */

    setcolor(12);
    setfillstyle(SOLID_FILL, 12);
    circle(x1, y1, 10);
    floodfill(x1, y1, 12);
    chessman[x1 / 30][y1 / 30] = PLAYER2;
    win_flag = win_or_not(x1, y1, 2, chessman, 0);
    if (win_flag == 2)
  outtextxy(480, 240, "P2 Win");
    else if (win_flag == 3)
  outtextxy(480, 240, "DOGFALL");
    if (win_flag != 0) {
  while (bioskey(1) == 0);
  closegraph();
    }
  }

   }
   break;
 }
   }
 }
  } else {
 chessman[7][7] = COMPUTER;       /*人和电脑玩,电脑先走一步*/
 setcolor(12);
 setfillstyle(SOLID_FILL, 12);
 circle(240, 240, 10);
 floodfill(240, 240, 12);
 flag_run = 0;          /*有什么用?*/
 step_sum++;          /*下一步谁走?*/
 while (1) {
   while (1) {
 if (flag_run == 1)
   break;
 if (bioskey(1)) {
   key = bioskey(0);
   /*
    * 返回一个键盘值,如没有按键,则一直等待
    */
   switch (key) {

   case ESC:
  exit(0);
   case LEFT:
  if (x1 > 30) {
    x1 -= 30;
    show();
  }
  break;
   case UP:
  if (y1 > 30) {
    y1 -= 30;
    show();
  }
  break;
   case RIGHT:
  if (x1 < 450) {
    x1 += 30;
    show();
  }
  break;
   case DOWN:
  if (y1 < 450) {
    y1 += 30;
    show();
  }
  break;
   case BLANK:
  {
    if (chessman[x1 / 30 - 1][y1 / 30 - 1])
  break;                             /*有棋子了不走*/

    setcolor(15);
    setfillstyle(SOLID_FILL, 15); /* 封闭图形,进行实体填充
     */
    circle(x1, y1, 10);
    floodfill(x1, y1, 15);               /*画棋子*/
    chessman[x1 / 30 - 1][y1 / 30 - 1] = PLAYER1;

    flag_run = 1;                 /*有什么用?*/
    step_sum++;                 /*下一步谁走*/
    win_flag = win_or_not(x1, y1, 1, chessman, 0);  /*谁胜谁负*/
    if (win_flag == 1)
  outtextxy(480, 240, "P1 Win");
    else if (win_flag == 3)
  outtextxy(480, 240, "DOGFALL");
    if (win_flag != 0) {
  while (bioskey(1) == 0);                 /*没有人胜则继续等待下棋*/
  closegraph();
    }

  }
   } /* switch */

 }

   }
   computer();                      /*调用智能体*/
   /*
   * a,b存放的是现在电脑准备下的位置
   * 返回一个a,b的结构体不是更好,用全局变量不爽啊
   * struct {
   *     int a;
   *     int b;
   * }
   */

   setcolor(12);
   setfillstyle(SOLID_FILL, 12);
   circle(a, b, 10);
   floodfill(a, b, 12);
   chessman[a / 30 - 1][b / 30 - 1] = COMPUTER;
   flag_run = 0;
   step_sum++;
   win_flag = win_or_not(a, b, 2, chessman, 0);
   if (win_flag == 2)
 outtextxy(480, 240, "ComputerWin");
   else if (win_flag == 3)
 outtextxy(480, 240, "DOGFALL");
   if (win_flag != 0) {
 while (bioskey(1) == 0);
 closegraph();
   }

 }
  }

}
void
five()
{
  int       i,
          j;
  /*
   * 画棋盘的过程
   */
  int       gdriver = DETECT,
          gmode;
  registerbgidriver(EGAVGA_driver);
  initgraph(&gdriver, &gmode, " ");
  /*
   * 对显示适配器进行配置
   */
  setbkcolor(1);

  for (i = 0; i < 30; i++) {
 setcolor((i >= 2) ? 9 : i);
 rectangle(i, i, 479 - i, 479 - i); /* 画矩形边框 */
  }
  /*
   * 画棋盘
   */
  for (i = 1; i < 14; i++)
 for (j = 1; j < 14; j++) {
   setcolor(14);
   line(30 + 30 * i, 30, 30 + 30 * i, 449);
   line(30, 30 + 30 * i, 449, 30 + 30 * i);
 }
  /*
   * 画整个图的边框
   */
  for (i = 0; i < 15; i++) {
 setcolor(i);
 rectangle(i, i, 640 - i, 480 - i);
 line(480 - i, 15, 480 - i, 465);
  }
  /*
   * 输出屏幕右侧的信息
   */
  setcolor(4);
  settextstyle(0, 0, 2);
  outtextxy(500, 45, "GOBANG");
  setcolor(10);
  settextstyle(0, 0, 1);
  outtextxy(500, 90, "Designed By");
  outtextxy(514, 118, "Ye Binbin");
  outtextxy(480, 140, "from class A of CS");

}

/*
 * 移动光标
 */
void
show()
{
  setcolor(1);

  if (oldx < 450) {
 if (oldy > 30)
   line(oldx + 7, oldy - 15, oldx + 15, oldy - 15);
 if (oldy > 30)
   line(oldx + 15, oldy - 15, oldx + 15, oldy - 7);
 if (oldy < 450)
   line(oldx + 15, oldy + 7, oldx + 15, oldy + 15);
 if (oldy < 450)
   line(oldx + 15, oldy + 15, oldx + 7, oldy + 15);
  }
  if (oldx > 30) {
 if (oldy < 450)
   line(oldx - 7, oldy + 15, oldx - 15, oldy + 15);
 if (oldy < 450)
   line(oldx - 15, oldy + 15, oldx - 15, oldy + 7);
 if (oldy > 30)
   line(oldx - 15, oldy - 7, oldx - 15, oldy - 15);
 if (oldy > 30)
   line(oldx - 15, oldy - 15, oldx - 7, oldy - 15);
  }
  setcolor(12);
  if (x1 < 450) {
 if (y1 > 30)
   line(x1 + 7, y1 - 15, x1 + 15, y1 - 15);
 if (y1 > 30)
   line(x1 + 15, y1 - 15, x1 + 15, y1 - 7);
 if (y1 < 450)
   line(x1 + 15, y1 + 7, x1 + 15, y1 + 15);
 if (y1 < 450)
   line(x1 + 15, y1 + 15, x1 + 7, y1 + 15);
  }

  if (x1 > 30) {
 if (y1 < 450)
   line(x1 - 7, y1 + 15, x1 - 15, y1 + 15);
 if (y1 < 450)
   line(x1 - 15, y1 + 15, x1 - 15, y1 + 7);
 if (y1 > 30)
   line(x1 - 15, y1 - 7, x1 - 15, y1 - 15);
 if (y1 > 30)
   line(x1 - 15, y1 - 15, x1 - 7, y1 - 15);
  }
  oldx = x1;
  oldy = y1;

}

void
set_chessman()
{
  /*
   * 棋子有三种状态,0是未初始状态,1是控制方棋子,2是对方棋子
   */
  int       i,
          j;
  for (i = 0; i < 15; i++)
 for (j = 0; j < 15; j++)
   chessman[i][j] = 0;
}

/*
 * 0表示没有赢,1表示p1胜利,2表示p2胜利,3表示平局
 */
int
win_or_not(int x0, int y0, int who, int chessman[LENGTH][LENGTH], int a)
{
  int       i = x0 / 30 - 1,
          j = y0 / 30 - 1;
  int       who_run = who;
  int       line_sum = -1;
  int       tmp_i = i,
          tmp_j = j;
  int       c;
  if (a == 1) {
 /*
 * 测试第一层扩展是否满足赢的条件
 */
 c = chessman[i][j];
 chessman[i][j] = who_run;
  }

  while (1) {  /* 查找共行的棋子是否连接了五个 */
 while (tmp_i >= 0 && line_sum != 4) {
   if (chessman[tmp_i--][j] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 4)
   line_sum++;
 tmp_i = i;
 while (tmp_i <= 15 && line_sum != 5) {
   if (chessman[tmp_i++][j] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 5) {
   if (a == 1)
 chessman[i][j] = c;
   return who_run;
 }
 line_sum = -1;
 tmp_i = i;
 break;

  }
  while (1) {  /* 查找共列的棋子是否连接了五个 */
 while (tmp_j >= 0 && line_sum != 4) {
   if (chessman[i][tmp_j--] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 4)
   line_sum++;
 tmp_j = j;
 while (tmp_j <= 15 && line_sum != 5) {
   if (chessman[i][tmp_j++] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 5) {
   if (a == 1)
 chessman[i][j] = c;
   return who_run;
 }
 line_sum = -1;
 tmp_j = j;
 break;

  }
  while (1) {  /* 查找上对角线上是否连接了五个 */
 while (line_sum != 4 && tmp_i <= 15 && tmp_j >= 0) {
   if (chessman[tmp_i++][tmp_j--] == who_run)
 line_sum++;
   else
 break;
 }
 tmp_i = i;
 tmp_j = j;
 if (line_sum == 4)
   line_sum++;
 while (line_sum != 5 && tmp_i >= 0 && tmp_j <= 15) {
   if (chessman[tmp_i--][tmp_j++] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 5) {
   if (a == 1)
 chessman[i][j] = c;
   return who_run;
 }
 tmp_i = i;
 tmp_j = j;
 line_sum = -1;
 break;
  }
  while (1) {  /* 查找下对角线上是否连接了五个 */
 while (line_sum != 4 && tmp_i >= 0 && tmp_j >= 0) {
   if (chessman[tmp_i--][tmp_j--] == who_run)
 line_sum++;
   else
 break;
 }
 tmp_i = i;
 tmp_j = j;
 if (line_sum == 4)
   line_sum++;
 while (line_sum != 5 && tmp_i <= 15 && tmp_j <= 15) {
   if (chessman[tmp_i++][tmp_j++] == who_run)
 line_sum++;
   else
 break;
 }
 if (line_sum == 5) {
   if (a == 1)
 chessman[i][j] = c;
   return who_run;
 }
 break;
  }
  if (step_sum == 225) {
 if (a == 1)
   chessman[i][j] = c;
 return 3;
  }
  if (a == 1)
 chessman[i][j] = c;
  return 0;

}

double
score_row(int i, int j, int chessman[LENGTH][LENGTH])
{
  int       sum_chessmen = 0;
  double     score = 0;
  int       mid_j;
  int       who_running = chessman[i][j];
  if (j == LENGTH) {
 while (chessman[i][j] == who_running) {
   j--;
   sum_chessmen++;
 }
 if (sum_chessmen >= 5)
   score = 200000;
 else {
   if (chessman[i][j] == 0) /* 没有下子,活的情况 */
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0; /* 死的情况 */
 }
  } else {
 while (chessman[i][j] == who_running && j != LENGTH) {
   j++;
   sum_chessmen++;
 }
 mid_j = j;
 j = j - sum_chessmen - 1;
 while (chessman[i][j] == who_running && j != -1) {
   j--;
   sum_chessmen++;
 }
 if (j >= 0 && mid_j < LENGTH) {
   if (chessman[i][j] == 0 && chessman[i][mid_j] == 0)
 score = 18000 / POW(50, 4 - sum_chessmen);
   else if ((chessman[i][j] != 0 && chessman[i][mid_j] == 0)
    || (chessman[i][j] == 0 && chessman[i][mid_j] != 0))
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0;
 }
 if (j < 0 && mid_j < LENGTH) {
   if (chessman[i][mid_j] == 0)
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0;
 }
 if (j >= 0 && mid_j >= LENGTH) {
   if (chessman[i][j] == 0)
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0;
 }
 if (j < 0 && mid_j >= LENGTH)
   score = 0;
  }
  return score;
}

double
score_col(int i, int j, int chessman[LENGTH][LENGTH])
{
  int       sum_chessmen = 0,
          mid_i;
  double     score = 0;
  int       who_running = chessman[i][j];
  if (i == LENGTH) {
 while (chessman[i][j] == who_running) {
   i--;
   sum_chessmen++;
 }
 if (sum_chessmen >= 5)
   score = 200000;
 if (chessman[i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
  } else {
 while (chessman[i][j] == who_running) {
   i++;
   sum_chessmen++;
 }
 mid_i = i;
 if (i == LENGTH || chessman[i][j] != who_running) {
   i = i - sum_chessmen;
   while (chessman[i - 1][j] == who_running) {
 i--;
 sum_chessmen++;
   }
   if (i >= 0) {
 if (chessman[i][j] == 0 && chessman[mid_i][j] == 0)
   score = 18000 / POW(50, 4 - sum_chessmen);
 else if ((chessman[i][j] != 0 && chessman[mid_i][j]) == 0
  || (chessman[i][j] == 0
    && chessman[mid_i][j] != 0))
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
   if (i < 0 && mid_i < LENGTH) {
 if (chessman[mid_i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
   if (i < 0 && mid_i < LENGTH) {
 if (chessman[mid_i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
   if (i >= 0 && mid_i >= LENGTH) {
 if (chessman[i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
 }
  }
  return score;
}

double
score_diag_45(int i, int j, int chessman[LENGTH][LENGTH])
{
  int       sum_chessmen = 0;
  double     score = 0;
  int       mid_i,
          mid_j;
  int       who_running = chessman[i][j];
  if (i == LENGTH || j == LENGTH) {
 while (chessman[i][j] == who_running && i > 1 && j > 1) {
   i--;
   j--;
   sum_chessmen++;
 }
 if (sum_chessmen >= 5)
   score = 200000;
 else {
   if (chessman[i][j] == 0)
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0;
 }
  } else {
 while (chessman[i][j] == who_running && i <= LENGTH && j <= LENGTH) {
   i++;
   j++;
   sum_chessmen++;
 }
 mid_i = i;
 mid_j = j;
 i = i - sum_chessmen;
 j = j - sum_chessmen;
 while (chessman[i - 1][j - 1] == who_running) {
   i--;
   j--;
   sum_chessmen++;
 }
 if (sum_chessmen >= 5)
   score = 200000;
 if (i >= 0 && j >= 0 && mid_i < LENGTH && mid_j < LENGTH) {
   if (chessman[mid_i][mid_j] == 0 && chessman[i][j] == 0)
 score = 18000 / POW(50, 4 - sum_chessmen);
   else if ((chessman[mid_i][mid_j] == 0 && chessman[i][j] != 0)
    || (chessman[mid_i][mid_j] != 0
  && chessman[i][j] == 0))
 score = 2000 / POW(10, 4 - sum_chessmen);
   else
 score = 0;
 } else {
   if (i >= 0 && j >= 0) {
 if (chessman[i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   } else if (mid_i < LENGTH && mid_j < LENGTH) {
 if (chessman[mid_i][mid_j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   } else
 score = 0;
 }
  }
  return score;
}

double
score_diag_135(int i, int j, int chessman[LENGTH][LENGTH])
{
  int       sum_chessmen = 0;
  double     score = 0;
  int       mid_i,
          mid_j;
  int       who_running = chessman[i][j];
  while (chessman[i][j] == who_running && j != -1 && i < LENGTH) {
 i++;
 j--;
 sum_chessmen++;
  }
  mid_i = i;
  mid_j = j;
  j += sum_chessmen;
  i -= sum_chessmen;
  j++;
  i--;
  while (chessman[i][j] == who_running && j != LENGTH) {
 i--;
 j++;
 sum_chessmen++;
  }
  if (sum_chessmen >= 5)
 score = 200000;
  else {
 if (i >= 0 && j < LENGTH && mid_j >= 0 && mid_i < LENGTH) {
   if (chessman[i][j] == 0 && chessman[mid_i][mid_j] == 0)
 score = 18000 / POW(50, 4 - sum_chessmen);
   else {
 if ((chessman[i][j] == 0 && chessman[mid_i][mid_j] != 0)
   || (chessman[i][j] != 0
  && chessman[mid_i][mid_j] == 0))
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
 } else {
   if (i >= 0 && j < LENGTH) {
 if (chessman[i][j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
   if (mid_j >= 0 && mid_i < LENGTH) {
 if (chessman[mid_i][mid_j] == 0)
   score = 2000 / POW(10, 4 - sum_chessmen);
 else
   score = 0;
   }
 }
  }
  return score;
}

double
total_score(int who_running, int chessman[LENGTH][LENGTH])
{
  /*
   * 统计出在该点上的得分,who_running=1表示人的棋子,2为电脑的棋子
   */
  int       i,
          j;
  double     score = 0;
  for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++) {
   if (chessman[i][j] == who_running) {
 score += score_row(i, j, chessman);
 score += score_col(i, j, chessman);
 score += score_diag_45(i, j, chessman);
 score += score_diag_135(i, j, chessman);
   }
 }
  return score;
}

double
score(int chessman[LENGTH][LENGTH])
{
  /*
   * 计算最终的得分数,分别考虑了在这个位置放对方棋子跟自己棋子的综合
   */
  double     sum1,
            sum2;
  sum1 = total_score(COMPUTER, chessman);
  sum2 = total_score(PLAYER1, chessman);
  return sum1 - sum2;
}

/*
 * 扩展-----剪枝过程
 */

int
rowdt(int i, int j, int chessman[LENGTH][LENGTH])  /*在树直方向*/
{
  int       k;
  int       midjl = j - STEP,         /*当前棋子的上方*/
          midjr = j + STEP + 1;     /*当前棋子的下方棋子的下方??????*/
  if (midjl < 0)
 midjl = 0;
  if (midjr > LENGTH)
 midjr = LENGTH;
  for (k = midjl; k < midjr; k++)       /**/
 if (chessman[i][k] != 0)         /*如果有棋子*/
   return 1;
  return 0;
}

int
coldt(int i, int j, int chessman[LENGTH][LENGTH])     /*水平方向*/
{
  int       k;
  int       midil = i + STEP + 1,         /*当前的右边棋子的右一个*/
          midiu = i - STEP;            /*当前棋子的左一个*/
  if (midiu < 0)
 midiu = 0;
  if (midil > LENGTH)
 midil = LENGTH;
  for (k = midiu; k < midil; k++)
 if (chessman[k][j] != 0)
   return 1;
  return 0;
}

int
diadt(int i, int j, int chessman[LENGTH][LENGTH])   /*右上到左下方向*/
{
  int       k,
          midi,
          midj;
  midi = i;
  midj = j;
  for (k = 0; k < STEP; k++) {
 midi++;
 midj--;
 if (midj < 0 || midi >= LENGTH)
   break;
 if (chessman[midi][midj] != 0)
   return 1;
  }
  for (k = 0; k < STEP; k++) {
 i--;
 j++;
 if (i < 0 || j >= LENGTH)
   break;
 if (chessman[i][j] != 0)
   return 1;
  }
  return 0;
}

int
vdiadt(int i, int j, int chessman[LENGTH][LENGTH])  /*左上到右下方向*/
{
  int       k,
          midi,
          midj;
  midi = i;
  midj = j;
  for (k = 0; k < STEP; k++) {
 midi--;
 midj--;
 if (midi < 0 || midj < 0)
   break;
 if (chessman[midi][midj] != 0)
   return 1;
  }
  for (k = 0; k < STEP; k++) {
 i++;
 j++;
 if (j >= LENGTH || i >= LENGTH)
   break;
 if (chessman[i][j] != 0)
   return 1;
  }
  return 0;
}

int
can_expand(int i, int j, int chessman[LENGTH][LENGTH])
{
  if (rowdt(i, j, chessman))
 return 1;
  if (coldt(i, j, chessman))
 return 1;
  if (diadt(i, j, chessman))
 return 1;
  if (vdiadt(i, j, chessman))
 return 1;
  /*
   * 如果不能扩展,返回0
   */
  return 0;
}

/************************************************************/
(0)

相关推荐

  • 纯C语言实现五子棋

    正在考虑增加一个MFC界面.不是人机对战的. 五子棋.c //date 2014年7月7日09:53:24 //willows //五子棋 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> //棋盘初始化函数 //Chessboard棋盘数组,ln=棋盘大小,成功返回Chessboard,不成功NULL void init_Chessboa

  • C++面向对象实现五子棋小游戏

    尽量将面向对象的思想融入进程序中 ChessBoard.h //ChessBoard.h #pragma once #define ROW 15 #define COL 15 #include<iostream> using namespace std; class ChessBoard//棋盘类 { public: char m_cSquare[ROW][COL]; public: ChessBoard(); void show(); }; ChessBoard.cpp //ChessBoa

  • 基于C++和MFC开发象棋程序

    这是我要和大家分享的基于C++和MFC开发的一个象棋程序,目的是练习编程实践和大家分享同时希望大家能给出指教. 进入主题 一.棋盘分析 这是我绘制的棋盘,棋盘的组成由9条竖线和10条横线构成.这儿我们设置每条线间的间隔是50. 二.绘制过程 1.在vs中新建MFC程序,去除环境自动生成的按钮和文字. 2.打开***Dlg.cpp文件,在void CChessDlg::OnPaint()中定义一个棋盘间隔值和绘图设备CDC *cd = CWnd::GetDC(); int nWid = 50; C

  • C语言实现五子棋小游戏

    首先我们先来看一个稍微简单些的实现方式: #include <stdio.h> #include <stdlib.h> #define N 15 int chessboard[N + 1][N + 1] = { 0 }; int whoseTurn = 0; void initGame(void); void printChessboard(void); void playChess(void); int judge(int, int); int main(void) { init

  • C++程序设计-五子棋

    前言:很多刚刚接触编程的人都不知道怎么下手编写程序,特别是学习了新的知识点,不知道有什么用,那么本文将以简单的存储结构及简单的运算,条件语句,分支语句,循环语句结合,带来一个双人对战版五子棋,这是一个简单的模型,实现了五子棋最最基本的功能,还有好多地方需要补全,如边界问题,设计问题,游戏逻辑问题,希望读者阅读后能够注意,通过自己的努力来完善它,还能扩展各种功能,如悔棋,网络对战等,有时候写程序和小生命一样,慢慢会成长,而我们作为"父母"的看到自己的小宝宝成为有用之才,过程之欣喜特别棒!

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

  • 基于C语言实现迷宫游戏的示例代码

    目录 C语言迷宫游戏 定义地图 打印地图方法一 打印地图方法二 定义起点和终点位置 实现读取按键 实现小球下向下移动一步 总结小球移动规律 实现重新打印地图 实现连续移动 实现小球下向上下左右移动 实现小球走到终点就胜利 C语言迷宫游戏 这篇文章是给学完并学懂了C语言的分支(选择和循环)结构和二维数组的朋友看的. 要做一个游戏或者程序先要想好有那些要求,以下是我认为一个迷宫必带的要求: 迷宫要先打印出来(要设置墙.空气.小球的起点),是墙就不能,是空气就可以走. 每次输入'w'.'a'.'s'.

  • 基于C语言实现的贪吃蛇游戏完整实例代码

    本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助. 贪吃蛇完整实现代码如下: #include <graphics.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #define NULL 0 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #defi

  • 基于C语言实现五子棋游戏

    采用二维数组制作五子棋,用坐标下棋. 请看代码. include<stdio.h> #include<string.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<time.h> void menu()//目录 { char xuanze = 0,xuanze2; printf("\n"); printf("\n&q

  • javascript实现的猜数小游戏完整实例代码

    本文实例讲述了javascript实现的猜数小游戏.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <

  • C语言版五子棋游戏的实现代码

    这次看了几位大佬的做法,我们也做了很多修改尝试.算是第一次尝试合作完成项目. 我认为学到的东西: 1.第一次尝试写项目,把函数分到不同的.c文件中后更好看了一些. 2.在研究过程中应该分清主次.代码正确运行才是基础要求,其他什么美化界面,调字体调颜色都并非重点. 3.从代码中学到的,①是采用落子数来判断该轮到黑方下还是白方下(落子数为2的倍数时黑方下,否则白方下),这样也能判断出是哪一方胜利,而且落子数还可以判断棋盘是否下满(==16*16时棋盘落满,平局) ②是胜利条件的判断,以中间子为参考,

  • 利用C语言实现五子棋游戏

    本文实例为大家分享了C语言实现五子棋游戏的具体代码,供大家参考,具体内容如下 一.前言 本文将先介绍五子棋运行所需要的函数,最后串联成完整代码. 我们需要实现的功能有:1.菜单menu函数 2.初始化棋盘Initboard函数 3.显示棋盘Displayboard函数 4.实现人机.人人模式的选择 5.落子函数 playermove  computermove 6.判断输赢ifwin函数 先来看看运行效果吧! 二.头文件 #define _CRT_SECURE_NO_WARNINGS #incl

  • C语言编写五子棋游戏

    本文实例为大家分享了C语言编写五子棋游戏的具体代码,供大家参考,具体内容如下 一.构建棋盘 首先可以用一个二维数组来构建棋盘,下标表示位置,内容表示黑子白子或者空位.当数组内容为1时,该位置为白字,当数组为0时,该位置为白子,空位输出+ int w[11][11], flag = 0; int a, b; for (int k = 0; k < 11; k++) printf("第%d列\t", k); printf("\n"); for (int i = 0

  • 使用C语言实现五子棋游戏

    目录 一.实现的目的和意义 二.实现内容描述 三.实现原理 四.实现模块五子棋实现分为三大模块 五.模块代码分析 六.实现结果 七.总结 本文实例为大家分享了C语言实现五子棋游戏的具体代码,供大家参考,具体内容如下 一.实现的目的和意义 1.巩固和加深对c语言知识的理解2.学会使用编译器的各种调试3.提高解决实际问题的能力 二.实现内容描述 实现简单的人人对战五子棋,此设计用的是C语言去实现 三.实现原理 采用二位数组保存棋盘信息,棋盘上面的任何一个位置,里头可以放三个信息: 1.空2.用户1的

  • java基于swing实现的五子棋游戏代码

    本文实例讲述了java基于swing实现的五子棋游戏代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Main extends JFrame implements ActionListener{         private static final long serialVersionUID = 1L;      

随机推荐