📄 board.cpp
字号:
////////////////////////////////////////////////////////////////////////////////// File : Board.cpp// Class : Board// Description : This class handels everything with board. drawing, event,// Player move, computer move// Author : Juergen P. Messerer, juergen.messerer@freesurf.ch// Project : Fl-Reversi// Release Date : 12th March 2003// Revised on :// License : Gnu Public License (GPL)//// Copyright(c) Juergen P. Messerer 2003./////////////////////////////////////////////////////////////////////////////////#include <FL/fl_ask.H>#include <FL/forms.H>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include "Board.h"#define BOXSIZE 34#define BORDER 2#define BOARDSIZE (8*BOXSIZE+BORDER)#define BMOFFSET 5Board::Board(int x, int y, int w, int h) { int row; int col; int fill; p_turnBox = new Fl_Box(0, 298, 66, 20, "Start Game"); p_turnBox->box(FL_DOWN_BOX); p_turnBox->labelsize(10); p_leftBox = new Fl_Box(66, 298, 100, 20, "Human (blue): "); p_leftBox->box(FL_DOWN_BOX); p_leftBox->labelsize(10); p_rightBox = new Fl_Box(166, 298, 110, 20, "Computer (red): "); p_rightBox->box(FL_DOWN_BOX); p_rightBox->labelsize(10); for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { int id = col + row * cols; if (!((row^col)&1)) fill = 1; else fill = 0; m_field[id] = new BoardElement(col*BOXSIZE, row*BOXSIZE+25, BOXSIZE, BOXSIZE, id, fill, this); m_field[id]->setState(empty); } } m_game_running = false; m_state = PLAYER_MOVE; m_strength = 4; m_animations = true; m_computerBegins = false;}//-----------------------------------------------------------------------------void Board::newGame(void){ m_game_running = false; engine.SetStrength(m_strength); game.Reset(); m_state = m_computerBegins ? COMPUTER_MOVE : PLAYER_MOVE; updateTurnLabel(m_state); m_game_running = true; updateBoard(); updateTurnLabel(m_state); if (m_computerBegins) { computerMove(); }}//-----------------------------------------------------------------------------void Board::fieldClicked(int id){ if (!m_game_running || (m_state != PLAYER_MOVE && m_state != HINT)) { return; } if (m_state == HINT) { updateTurnLabel( HINT ); m_field[id]->setState(empty); m_field[id]->redraw(); m_state = PLAYER_MOVE; m_field[id]->redraw(); } else { if (m_state == PLAYER_MOVE) { updateTurnLabel( PLAYER_MOVE ); Move move((id % cols) + 1, (id / cols) + 1, PlayerColor()); if (game.MakeMove(move)) { m_state = PLAYER_TURN; turnFields(move); if (!game.MoveIsAtAllPossible()) { gameOver(); } else { computerMove(); } } } }}//-----------------------------------------------------------------------------void Board::gameOver(void){ char msg[100]; int player = game.GetScore(PlayerColor()); int computer = game.GetScore(ComputerColor()); if(player < computer) sprintf( msg, "Game over\nYou loose %d:%d", player, computer ); else sprintf( msg, "Game over\nYou win %d:%d", player, computer ); updateTurnLabel( END ); fl_alert(msg);}//-----------------------------------------------------------------------------int Board::PlayerColor(void){ return m_computerBegins ? Score::WHITE : Score::BLACK;}//-----------------------------------------------------------------------------int Board::ComputerColor(void){ return m_computerBegins ? Score::BLACK : Score::WHITE;}//-----------------------------------------------------------------------------void Board::computerMove(void){ usleep(100000); if (game.GetWhoseTurn() != ComputerColor() || !game.MoveIsPossible(ComputerColor()) ) { m_state = PLAYER_MOVE; return; } m_state = COMPUTER_MOVE; do { if (!game.MoveIsAtAllPossible()) { gameOver(); return; } Move move = engine.ComputeMove(game); if (move.GetX() == -1) { m_state = PLAYER_MOVE; return; } m_state = COMPUTER_TURN; game.MakeMove(move); turnFields(move); } while (!game.MoveIsPossible(PlayerColor())); m_state = PLAYER_MOVE; if (!game.MoveIsAtAllPossible()) { gameOver(); }}//-----------------------------------------------------------------------------void Board::drawField(int col, int row, int state){ int id = col + row * cols; if (id >= 0 && id < (rows * cols) && state >= empty && state <= red) { m_field[id]->setState(state); m_field[id]->redraw(); }}//-----------------------------------------------------------------------------void Board::turnFieldsRow(int row, int col, int dy, int dx){ row = row + dy; col = col + dx; while (row >= 0 && row < rows && col >= 0 && col < cols) { if (game.wasTurned(col + 1, row + 1)) { int color = game.GetSquare(col + 1, row + 1); int from; int to; int delta; int i; if (color == PlayerColor()) { from = red - 2; to = blue + 2; delta = -1; } else { if (color == ComputerColor()) { from = blue + 2; to = red - 2; delta = 1; } else { break; } } for (i = from; i != to; i = i + delta) { drawField(col, row, i); usleep(15000); } drawField(col, row, color == PlayerColor() ? blue : red); usleep(250000); } else { break; } row = row + dy; col = col + dx; }}//-----------------------------------------------------------------------------void Board::turnFields(Move &move){ if (m_animations) { int row = move.GetY() - 1; int col = move.GetX() - 1; int dx; int dy; drawField(col, row, move.GetPlayer() == PlayerColor() ? blue : red); for (dx = -1; dx <= 1; dx++) { for (dy = -1; dy <= 1; dy++) { if (dx || dy) { turnFieldsRow(row, col, dy, dx); } } } } else { updateBoard(); }}//-----------------------------------------------------------------------------void Board::updateBoard(void){ int row; int col; for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { int id = col + row * cols; int color = game.GetSquare(col + 1, row + 1); if (color == PlayerColor()) { m_field[id]->setState(blue); } else { if (color == ComputerColor()) { m_field[id]->setState(red); } else { m_field[id]->setState(empty); } } m_field[id]->redraw(); } } updateScoreLabel();}//-----------------------------------------------------------------------------void Board::updateStrength(int strength){ if (strength != m_strength) { m_strength = strength; engine.SetStrength(m_strength); }}//-----------------------------------------------------------------------------void Board::updateAnimations(int animations){ if ((animations != 0) != m_animations) { m_animations = animations ? true : false; }}//-----------------------------------------------------------------------------void Board::updateComputerBegins(int computerBegins){ if ((computerBegins != 0) != m_computerBegins) { m_computerBegins = computerBegins ? true : false; if (m_game_running) { newGame(); } }}//-----------------------------------------------------------------------------void Board::undoMove(void){ if (!m_game_running || m_state != PLAYER_MOVE || game.GetMoveNumber() == 0) { return; } game.TakeBackMove(); game.TakeBackMove(); updateBoard();}//-----------------------------------------------------------------------------void Board::getHint(void){ if (!m_game_running || m_state != PLAYER_MOVE) { return; } Move move = engine.ComputeMove(game); int row = move.GetY() - 1; int col = move.GetX() - 1; if (row >= 0 && col >= 0) { int id = col + row * cols; int i; m_state = HINT; for (i = 0; i < 240 && m_state == HINT; ++i) { if (m_field[id]->state() == blue) { m_field[id]->setState(empty); } else { m_field[id]->setState(blue); } m_field[id]->redraw(); /*for (int j = 0; j < 5; ++j) { usleep(50000); }*/ } } m_state = PLAYER_MOVE; }//-----------------------------------------------------------------------------void Board::updateTurnLabel( int state ){ switch ( state ) { case Board::PLAYER_MOVE: p_turnBox->label("Your turn"); break; case Board::PLAYER_TURN: case Board::COMPUTER_TURN: p_turnBox->label("Turning chips..."); break; case Board::COMPUTER_MOVE: p_turnBox->label("Thinking..."); break; case Board::HINT: p_turnBox->label("Hint..."); break; case Board::END: p_turnBox->label("Game Over"); break; } p_turnBox->redraw();}//-----------------------------------------------------------------------------void Board::updateScoreLabel(){ char buf[80]; int player = game.GetScore(PlayerColor()); int computer = game.GetScore(ComputerColor()); sprintf(buf,"Human (blue):%2d", (int)player); p_leftBox->label( strdup(buf) ); p_leftBox->redraw(); sprintf(buf,"Computer (red):%2d", computer); p_rightBox->label( strdup(buf) ); p_rightBox->redraw();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -