⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moveplayer.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
字号:
/***
 * File:   MovePlayer.cpp - Implements MovePlayer.h
 *         -----------------------------------------------------
 * Author: Peter Dalton
 * Date:   3/13/2001 9:53:22 AM
 *
 * Description:
			This class is responsible for generating all posible moves and for actually making 
			moves.
 *
 * Copyright (C) Peter Dalton, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied warranties. You may freely copy 
 * and compile this source into applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 *                  "Portions Copyright (C) Peter Dalton, 2001"
 */

#include "MemoryManager.h"

#include "Board.h"
#include "MoveTree.h"
#include "Path.h"
#include "MovePlayer.h"

/*******************************************************************************************/
/*******************************************************************************************/
// ***** Implementation of the MovePlayer Class

/**
 * MovePlayer::MovePlayer():
 *  Constructor
 * 
 *  Return Type : 
 *  Arguments   : 
 *  	Board* bd	: The current game board.
 */
MovePlayer::MovePlayer( Board* bd ) : m_board(bd)
{}

/*******************************************************************************************/

/**
 * MovePlayer::~MovePlayer():
 *  Destructor.
 * 
 *  Return Type : 
 *  Arguments   : 
 */
MovePlayer::~MovePlayer( void )
{}

/*******************************************************************************************/

/**
 * MovePlayer::makeMove():
 *  This method is responsible for making the desired move and updating the game board.  
 *  The following is a list of return values:
 *       -2 -> Must make a jump when available.
 *       -1 -> Ambiguous move.
 *        0 -> Tryed to make an invalid move.
 *        1 -> Valid move.
 * 
 *  Return Type : int -> One of the return types listed above.
 *  Arguments   : 
 *  	int path[]	  : The path describing the desired move.
 *  	bool redsTurn	: Whether or not it is reds turn.
 */
int MovePlayer::makeMove( pathValue path[], bool redsTurn )
{
	piece ptemp;
	bool mustJump = canJump( redsTurn );
	bool validMove = false;

	if (path[0] <= 1) return -1;
	
	ptemp = m_board->get( path[1] );
	if (redsTurn) {
		if (ptemp != red && ptemp != RED)     return 0;
	}
	else {
		if (ptemp != white && ptemp != WHITE) return 0;
	}

	if (mustJump) {
		if (ptemp == red) {              // Red Pawn
			if (validateJump( SW, NUM_DIR, path )) validMove = true; 
		}
		else if (ptemp == white) {       // White Pawn
			if (validateJump( NW, SW, path ))      validMove = true; 
		}
		else {                           // Red or White King
			if (validateJump( NW, NUM_DIR, path )) validMove = true; 
		}

		if (!validMove) return -2;       // Invalid Move, must make a jump when available.
	}
	else {
		if (path[0] > 2) return 0;       // A slide can only be defined by 2 states.

		if (ptemp == red) {              // Red Pawn
			if (validateSlide( SW, NUM_DIR, path )) validMove = true;
		}
		else if (ptemp == white) {       // White Pawn
			if (validateSlide( NW, SW, path ))      validMove = true;
		}
		else {                           // Red or White King
			if (validateSlide( NW, NUM_DIR, path )) validMove = true;
		}

		if (!validMove) return 0;        // Invalid Move!!
	}

	// Actually make the move now that it has been validated.
	if (mustJump) {
		for (int ii = 1; ii < path[0]; ++ii) {
			m_board->updateJump( path[ii], path[ii+1] );
		}
	}
	else {
		m_board->updateSlide( path[1], path[2] );
	}
	return 1;
}

/*******************************************************************************************/

/**
 * MovePlayer::canJump():
 *  Returns TRUE if it is possible to jump, otherwise FALSE.
 * 
 *  Return Type : bool -> Whether or not it is possible to make a jump.
 *  Arguments   : 
 *  	bool redsTurn	: Whether or not it is reds turn.
 */
bool MovePlayer::canJump( bool redsTurn )
{
  piece ptemp;
  int ii, curDir, dest;
	int Direction;

  if (redsTurn) { // We are moving red
    for (ii = 1; ii < BOARD_SIZE; ++ii) {
			ptemp = m_board->get( ii );

			if (ptemp == red)      Direction = SW;
			else if (ptemp == RED) Direction = NW;
			else                   continue;
			
			for (curDir = Direction; curDir < NUM_DIR; ++curDir) {
				dest = Board::SLIDE[ii][curDir];
				if (dest != 0) {                                             // It is possible to jump from this position.
					ptemp = m_board->get( dest );
					if (ptemp != red && ptemp != RED && ptemp != empty) {      // There is an enemy piece to jump.
						dest = Board::SLIDE[dest][curDir];
						if (dest) {
							if (m_board->get( dest ) == empty) return true;        // The spot on the other side of the enemy
						}                                                        // is empty.
					}
				}
			}
    } 
  } 
  else {         // We are moving white
    for (ii = 1; ii < BOARD_SIZE; ++ii) {
			ptemp = m_board->get( ii );

			if (ptemp == white)      Direction = SW;
			else if (ptemp == WHITE) Direction = NUM_DIR;
			else                     continue;

			for (curDir = NW; curDir < Direction; ++curDir) {
				dest = Board::SLIDE[ii][curDir];

				if (dest != 0) {                                             // It is possible to jump from this position.
					ptemp = m_board->get( dest );
					if (ptemp != white && ptemp != WHITE && ptemp != empty) {  // There is an enemy piece to jump.
						dest = Board::SLIDE[dest][curDir];
						if (dest) {
							if (m_board->get( dest ) == empty) return true;        // The spot on the other side of the enemy
						}                                                        // is empty.
					}
				}
			}
    }
  }
  return false;
}

/*******************************************************************************************/

/**
 * MovePlayer::generateMoves():
 *  Given the current state of the board and which players turn it is this method determines
 *  all possible moves.  All moves are stored within the provided PathList.
 * 
 *  Return Type : void 
 *  Arguments   : 
 *  	bool redsTurn	      : Whether or not it is red's turn.
 *  	PathList& endStates	: A linked list to hold all possible moves.
 */
void MovePlayer::generateMoves( bool redsTurn, PathList& endStates )
{
  piece ptemp;
  int ii;
   
	MoveTree moves; 
  bool mustJump = canJump( redsTurn );

  if (redsTurn) {                        // We are moving Red
    for (ii = 1; ii < BOARD_SIZE; ++ii) {
			ptemp = m_board->get( ii );
			if (ptemp == red) {                // Red Pawn
				moves.Initialize( m_board, ii, red, RED, SW, NUM_DIR );
				moves.generateMoves( endStates, ii, mustJump );
			}
			else if (ptemp == RED) {           // Red King
				moves.Initialize( m_board, ii, RED, red, NW, NUM_DIR);
				moves.generateMoves( endStates, ii, mustJump );
			}
    } 
  } 
  else {                                 // We are moving White 
		for (ii = 1; ii < BOARD_SIZE; ++ii) {
			ptemp = m_board->get( ii );
			if (ptemp == white) {              // White Pawn
				moves.Initialize( m_board, ii, white, WHITE, NW, SW );
				moves.generateMoves( endStates, ii, mustJump );
			}
			else if (ptemp == WHITE) {         // White King
				moves.Initialize( m_board, ii, WHITE, white, NW, NUM_DIR );
				moves.generateMoves( endStates, ii, mustJump );
			}
    }
  }
}

/*******************************************************************************************/

/**
 * MovePlayer::validateSlide():
 *  Determines whether or given move path is a valid slide or not.
 * 
 *  Return Type : bool -> Whether or not the given move path is a valid slide.
 *  Arguments   : 
 *  	int startDir	   : The starting board coordinate for possible moves.
 *  	int endDir	     : The ending board coordinate for possible moves.
 *  	pathValue path[] : The desired move path.
 */
bool MovePlayer::validateSlide( int startDir, int endDir, pathValue path[] )
{
	for (int ii = startDir; ii < endDir; ++ii) {
		if (Board::SLIDE[path[1]][ii] == path[2] && m_board->get( path[2] ) == empty) {
			return true;
		}
	}
	return false;
}

/*******************************************************************************************/

/**
 * MovePlayer::validateJump():
 *  Determines whether or given move path is a valid jump or not.
 * 
 *  Return Type : bool -> Whether or not the given move path is a valid jump.
 *  Arguments   : 
 *  	int startDir	   : The starting board coordinate for possible moves.
 *  	int endDir	     : The ending board coordinate for possible moves.
 *  	pathValue path[] : The desired move path.
 */
bool MovePlayer::validateJump( int startDir, int endDir, pathValue path[] ) 
{
	PathList list;
	MoveTree jumpTree;

	piece ptemp = m_board->get( path[1] );

	if (ptemp == red || ptemp == RED) {
		jumpTree.Initialize( m_board, path[1], red, RED, startDir, endDir );
	}
	else {
		jumpTree.Initialize( m_board, path[1], WHITE, white, startDir, endDir );
	}

	jumpTree.generateMoves( list, path[1], true );

	for (int ii = 0; ii < list.getLength(); ++ii) {
		if (list.pathsEqual( path, ii )) return true;
	}
	return false;
}

// ***** End of MovePlayer.cpp
/*******************************************************************************************/
/*******************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -