/*************************************** 程序名称:五子棋 **** 编译环境:vs2012 **** 编辑作者:往事随风<1034882113> **** 最后修改:2013-07-25 **** 项目类型:win32控制台程序 ****************************************/#include<graphics.h>#include<conio.h>// _kbhit() _getch()/****************** 宏定义区 **********************/#define BOARD_LEN 640 // 棋盘大小#define BOARD_WIDTH 640#define EXTRA_LEN 200 // 右边提示区域的长度#define SIZE 40 // 棋盘小方格大小#define ROW 14 // 棋盘为14*14/****************** 数据类型定义区******************//****************** 全局变量区**********************/IMAGE img_chessboard; // 背景IMAGE img_box_black; // 黑色棋盒IMAGE img_box_white; // 白色棋盒IMAGE img_bkbox; // 右边区域背景IMAGE img_time; // 显示时间IMAGE img_count[11]; // 十个数字和一个冒号int m_x = (BOARD_LEN - SIZE * ROW)/2; // 居中int m_y = (BOARD_WIDTH - SIZE * ROW)/2;byte gobang[ROW+1][ROW+1] = {0};// byte不能表示负数0:无子1:黑子2:白子byte type = 0; // 1: 白棋0:黑棋bool replay = true; // false 游戏结束,true代表游戏运行中DWORD b_oldtime; // 黑棋花费时间DWORD w_oldtime; // 白棋花费时间DWORD start_time; // 游戏起始时间/****************** 函数声明区**********************/void init_system();void init_img();void init_chessboard();void getMouse(POINT *point);void deal_mousemsg(POINT point);void game_win(int x,int y);void quit_game();void print_msg();void show_time(DWORD newtime);void print_time(DWORD time);/****************** 主函数区 **********************/ void main(){POINT point; // 存储坐标位置while (true){init_system();while (replay){getMouse(&point);deal_mousemsg(point);}}}/****************** 函数定义区**********************/void print_time(DWORD time){int y = 0;int minuteh = time / (600*1000); // 分钟十位time %= (600*1000);int minutel = time / (60*1000); // 分钟个位time %= (60*1000);int secondh = time / (10*1000); // 秒钟十位int secondl = time % (10*1000); // 秒钟个位int x = BOARD_LEN + 5 - m_x;if (type) // 白棋y = EXTRA_LEN + 5 - m_y;else y = BOARD_WIDTH/2+EXTRA_LEN+5 - m_y; // 黑棋putimage(x+80,y+45,&img_count[minuteh]); // 分钟十位putimage(x+95,y+45,&img_count[minutel]); // 分钟个位putimage(x+125,y+45,&img_count[secondh]); // 秒十位putimage(x+140,y+45,&img_count[secondl/1000]); // 秒个位}/* 显示倒计时 */void show_time(DWORD newtime){DWORD tmp = b_oldtime+w_oldtime + start_time; // 游戏运行的时间if (type) // 白棋{w_oldtime += newtime - tmp; // 计算白棋用的时间print_time(w_oldtime);}else// 黑棋{b_oldtime += newtime - tmp; // 计算黑棋用的时间print_time(b_oldtime);}}/* 打印右边游戏信息 */void print_msg(){outtextxy(20,50,_T("倒计时:"));putimage(80,45,&img_count[0]);putimage(95,45,&img_count[0]);putimage(110,45,&img_count[10]);putimage(125,45,&img_count[0]);putimage(140,45,&img_count[0]);outtextxy(20,80,_T("比分:"));outtextxy(80,80,_T("0"));}/* 结束游戏 */void quit_game(){closegraph();exit(0);}/* 判断胜利 */void game_win(int x,int y){int i = -5,j = -5;int count = 0;byte flag = gobang[x][y]; // 判断棋色while (count != 5 && ++i < 5) // 横{if (gobang[x+i][y] == flag)count++;else count = 0;}while (count != 5 && ++j < 5) // 竖{if (gobang[x][y+j] == flag)count++;else count = 0;}i = j = -5;while (count != 5 && ++i < 5 && ++j < 5) // 左斜{if (gobang[x+i][y+j] == flag)count++;else count = 0;}i = 5;j = -5;while (count != 5 && --i > -5 && ++j < 5) // 右斜{if (gobang[x+i][y+j] == flag)count++;else count = 0;}if (count == 5){setbkmode(TRANSPARENT); // 设置文字背景透明settextstyle(48, 0, _T("宋体"));settextcolor(RED);if (flag == 1)outtextxy(BOARD_LEN/3,BOARD_WIDTH/3,_T("BLACK WIN"));else outtextxy(BOARD_LEN/3,BOARD_WIDTH/3,_T("WHITE WIN"));HWND wnd = GetHWnd();if (MessageBox(wnd, _T("要再来一局吗?"), _T("提醒"),MB_OKCANCEL | MB_ICONQUESTION) == IDOK){replay = false;Sleep(200);}else quit_game();}}/* 画棋子 */void deal_mousemsg(POINT point){int r = SIZE/2; // 取点范围int x0 = (point.x - m_x) / SIZE + (point.x - m_x)%SIZE/r;int y0 = (point.y - m_y) / SIZE + (point.y - m_y)%SIZE/r;if (type) // 判断棋手1:白棋0:黑棋setfillcolor(WHITE);else setfillcolor(BLACK);if (x0 >= 0 && x0 <= ROW && // 判断边界y0 >= 0 && y0 <= ROW &&gobang[x0][y0] == 0) // 无子状态才下子{fillcircle(x0*SIZE,y0*SIZE,SIZE/3);gobang[x0][y0] = 1 + (1&&type); // 置为有子状态(必须位于判断输赢前) game_win(x0,y0);type = 1 ^ type; // 换手}}/* */void getMouse(POINT *point){HWND hwnd = GetHWnd(); // 获取绘图窗口句柄MOUSEMSG msg;FlushMouseMsgBuffer();while (true) // 等待鼠标点击{DWORD newtime = GetTickCount(); // 获取系统时间if (newtime - w_oldtime - b_oldtime > 1000)show_time(newtime); // 显示时间if (MouseHit()){msg = GetMouseMsg();if (msg.uMsg ==WM_LBUTTONDOWN){GetCursorPos(point); // 获取鼠标指针位置(屏幕坐标)ScreenToClient(hwnd,point); // 将鼠标指针位置转换为窗口坐标break;}}}}/* 初始化棋盘 */void init_chessboard(){int i = 0, j = 0;init_img(); // 初始化图片资源putimage(0,0,&img_chessboard); // 输出棋盘putimage(BOARD_LEN,0,&img_bkbox); // 输出右边背景putimage(BOARD_LEN,0,&img_box_white); // 输出白色棋盒putimage(BOARD_LEN,BOARD_WIDTH/2,&img_box_black); // 输出黑色棋盒setcolor(BLACK);rectangle(BOARD_LEN+5,EXTRA_LEN+5,BOARD_LEN+EXTRA_LEN-5,BOARD_WIDTH/2-5);rectangle(BOARD_LEN+5,BOARD_WIDTH/2+EXTRA_LEN+5,BOARD_LEN+EXTRA_LEN-5,BOARD_WIDTH-5);setbkmode(TRANSPARENT);setorigin(BOARD_LEN+5,EXTRA_LEN+5); // 上面的矩形白子outtextxy(20,20,_T("undefined"));print_msg();setorigin(BOARD_LEN+5,BOARD_WIDTH/2+EXTRA_LEN+5); // 下面的矩形黑子outtextxy(20,20,_T("电脑"));print_msg();setcolor(BLACK);setorigin(m_x,m_y); // 设置原点for (i = 0; i <= ROW; i++){line(0,0+i*SIZE,0+SIZE*ROW,0+i*SIZE); // 横线line(0+i*SIZE,0,0+i*SIZE,0+SIZE*ROW); // 竖线}}void init_img(){int i = 0;loadimage(&img_chessboard,_T("./res/chess_board.jpg"),BOARD_LEN,BOARD_WIDTH,true);loadimage(&img_box_white,_T("./res/box_white1.bmp"),EXTRA_LEN,EXTRA_LEN,true);loadimage(&img_box_black,_T("./res/box_black1.bmp"),EXTRA_LEN,EXTRA_LEN,true);loadimage(&img_bkbox,_T("./res/bkbox.bmp"),EXTRA_LEN,BOARD_WIDTH,true);loadimage(&img_time,_T("./res/time.bmp"),15,250,true);SetWorkingImage(&img_time);for (i = 0; i < 10; i++) // 初始化十个数字getimage(&img_count[i],0,i*25,15,25);loadimage(&img_count[10],_T("./res/dot.bmp"),15,25,true);SetWorkingImage(NULL);}void init_system(){int i = 0, j = 0;initgraph(BOARD_LEN+EXTRA_LEN+10,BOARD_WIDTH+10);init_chessboard();replay = true;ZeroMemory(gobang,(ROW+1)*(ROW+1)); // 初始化数组为0b_oldtime = 0;w_oldtime = 0;start_time = GetTickCount();}。