📄 playfield.cpp
字号:
/* * Copyright (C) 2002 Robert Ernst <robert.ernst@linux-solutions.at> * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation and appearing in the file LICENSE.GPL included in the * packaging of this file. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * See COPYING for GPL licensing information. * */#include <qpe/qpeapplication.h>#include <qmessagebox.h>#include <qwidget.h>#include <qpainter.h>#include <qfont.h>#include <qfontmetrics.h>#include "PlayField.h"#include "SpriteCollection.h"#include "Engine.h"#include "Game.h"#include "Score.h"#include "Move.h"#include <stdlib.h>#include <unistd.h>PlayField::PlayField(QWidget *parent, const char *name, WFlags f) : QWidget(parent, name, f){ int row; int col; m_sprites = new SpriteCollection(this); for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { int id = col + row * cols; m_tile[id] = new PlayTile(this, m_sprites, id); m_tile[id]->setState(empty); m_tile[id]->move(col * tilesize, row * tilesize + 22); m_tile[id]->setFixedSize(tilesize, tilesize); m_tile[id]->show(); connect(m_tile[id], SIGNAL(tileClicked(int)), this, SLOT(tileClicked(int))); } } m_game_running = false; m_state = PLAYER_MOVE; m_strength = 4; m_animations = true; m_computerBegins = false;}PlayField::~PlayField(){ int row; int col; for (row = 0; row < rows; row++) { for (col = 0; col < cols; col++) { int id = col + row * cols; if (m_tile[id]) { delete m_tile[id]; } } } if (m_sprites) { delete m_sprites; }}void PlayField::paintEvent(QPaintEvent *event){ if (!m_game_running) { start(); return; } QPainter painter(this); QString label(""); QColor black(0, 0, 0); switch (m_state) { case PLAYER_MOVE: label = tr("Your turn"); break; case PLAYER_TURN: case COMPUTER_TURN: label = tr("Turning chips..."); break; case COMPUTER_MOVE: label = tr("Thinking..."); break; case HINT: label = tr("Hint..."); break; } painter.setPen(black); painter.drawText(7, 0, width(), 22, AlignLeft | AlignVCenter, label);}void PlayField::tileClicked(int id){ if (!m_game_running || (m_state != PLAYER_MOVE && m_state != HINT)) { return; } if (m_state == HINT) { m_tile[id]->setState(empty); m_tile[id]->repaint(false); m_state = PLAYER_MOVE; repaint(0, 0, width(), 22); } else if (m_state == PLAYER_MOVE) { Move move((id % cols) + 1, (id / cols) + 1, PlayerColor()); if (game.MakeMove(move)) { m_state = PLAYER_TURN; repaint(0, 0, width(), 22); turnTiles(move); if (!game.MoveIsAtAllPossible()) { gameOver(); start(); } else { computerMove(); } } }}void PlayField::gameOver(void){ int player = game.GetScore(PlayerColor()); int computer = game.GetScore(ComputerColor()); QString score = (player < computer) ? tr("Game over\nYou loose %1:%2").arg(player).arg(computer) : tr("Game over\nYou win %1:%2").arg(player).arg(computer); QMessageBox::information(this, tr("Reversi"), score);}int PlayField::PlayerColor(void){ return m_computerBegins ? Score::WHITE : Score::BLACK;}int PlayField::ComputerColor(void){ return m_computerBegins ? Score::BLACK : Score::WHITE;}void PlayField::computerMove(void){ if (game.GetWhoseTurn() != ComputerColor() || !game.MoveIsPossible(ComputerColor())) { m_state = PLAYER_MOVE; repaint(0, 0, width(), 22); return; } m_state = COMPUTER_MOVE; repaint(0, 0, width(), 22); do { if (!game.MoveIsAtAllPossible()) { gameOver(); start(); return; } Move move = engine.ComputeMove(game); if (move.GetX() == -1) { m_state = PLAYER_MOVE; repaint(0, 0, width(), 22); return; } m_state = COMPUTER_TURN; repaint(0, 0, width(), 22); game.MakeMove(move); turnTiles(move); } while (!game.MoveIsPossible(PlayerColor())); m_state = PLAYER_MOVE; repaint(0, 0, width(), 22); if (!game.MoveIsAtAllPossible()) { gameOver(); start(); }}void PlayField::drawTile(int col, int row, int state){ int id = col + row * cols; if (id >= 0 && id < (rows * cols) && state >= empty && state <= red) { m_tile[id]->setState(state); m_tile[id]->repaint(false); }}void PlayField::turnTilesRow(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) { drawTile(col, row, i); usleep(15000); } drawTile(col, row, color == PlayerColor() ? blue : red); usleep(250000); } else { break; } row = row + dy; col = col + dx; }}void PlayField::turnTiles(Move &move){ if (m_animations) { int row = move.GetY() - 1; int col = move.GetX() - 1; int dx; int dy; drawTile(col, row, move.GetPlayer() == PlayerColor() ? blue : red); for (dx = -1; dx <= 1; dx++) { for (dy = -1; dy <= 1; dy++) { if (dx || dy) { turnTilesRow(row, col, dy, dx); } } } } else { updateBoard(); }}void PlayField::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_tile[id]->setState(blue); } else if (color == ComputerColor()) { m_tile[id]->setState(red); } else { m_tile[id]->setState(empty); } m_tile[id]->repaint(false); } }}void PlayField::updateStrength(int strength){ if (strength != m_strength) { m_strength = strength; if (m_game_running) { start(); } }}void PlayField::updateAnimations(int animations){ if ((animations != 0) != m_animations) { m_animations = animations ? true : false; }}void PlayField::updateComputerBegins(int computerBegins){ if ((computerBegins != 0) != m_computerBegins) { m_computerBegins = computerBegins ? true : false; if (m_game_running) { start(); } }}void PlayField::start(void){ m_game_running = false; engine.SetStrength(m_strength); game.Reset(); m_state = m_computerBegins ? COMPUTER_MOVE : PLAYER_MOVE; m_game_running = true; updateBoard(); if (m_computerBegins) { computerMove(); }}void PlayField::back(void){ if (!m_game_running || m_state != PLAYER_MOVE || game.GetMoveNumber() == 0) { return; } game.TakeBackMove(); game.TakeBackMove(); updateBoard();}void PlayField::hint(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; repaint(0, 0, width(), 22); for (i = 0; i < 240 && m_state == HINT; i++) { if (m_tile[id]->state() == blue) { m_tile[id]->setState(empty); } else { m_tile[id]->setState(blue); } m_tile[id]->repaint(false); for (i = 0; i < 5; i++) { usleep(50000); qApp->processEvents(); } } } m_state = PLAYER_MOVE; repaint(0, 0, width(), 22);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -