You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/kjumpingcube/cubebox.cpp

293 lines
6.1 KiB

/* ****************************************************************************
This file is part of the game 'KJumpingCube'
Copyright (C) 1998-2000 by Matthias Kiefer
<matthias.kiefer@gmx.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**************************************************************************** */
#include <assert.h>
#include <math.h>
#include "cubebox.h"
#include "kcubeboxwidget.h"
CubeBox::CubeBox(const int d)
:CubeBoxBase<Cube>(d)
{
initCubes();
}
CubeBox::CubeBox(const CubeBox& box)
:CubeBoxBase<Cube>(box.dim())
{
initCubes();
int i,j;
for(i=0;i<dim();i++)
for(j=0;j<dim();j++)
{
*cubes[i][j]=*box.cubes[i][j];
}
currentPlayer=box.currentPlayer;
}
CubeBox::CubeBox(KCubeBoxWidget& box)
:CubeBoxBase<Cube>(box.dim())
{
initCubes();
int i,j;
for(i=0;i<dim();i++)
for(j=0;j<dim();j++)
{
*cubes[i][j]=*box[i][j];
}
currentPlayer=(CubeBox::Player)box.player();
}
CubeBox::~CubeBox()
{
}
CubeBox& CubeBox::operator=(const CubeBox& box)
{
if(this!=&box)
{
if(dim()!=box.dim())
{
setDim(box.dim());
}
for(int i=0;i<dim();i++)
for(int j=0;j<dim();j++)
{
*cubes[i][j]=*box.cubes[i][j];
}
}
currentPlayer=box.currentPlayer;
return *this;
}
CubeBox& CubeBox::operator=(KCubeBoxWidget& box)
{
if(dim()!=box.dim())
{
setDim(box.dim());
}
for(int i=0;i<dim();i++)
for(int j=0;j<dim();j++)
{
*cubes[i][j]=*box[i][j];
}
currentPlayer=(CubeBox::Player)box.player();
return *this;
}
bool CubeBox::simulateMove(Player fromWhom,int row, int column)
{
bool finished;
bool playerWon=false;
if(cubes[row][column]->owner()!=(Cube::Owner)fromWhom && cubes[row][column]->owner()!=Cube::Nobody)
return false;
cubes[row][column]->increase((Cube::Owner)fromWhom);
do
{
int i,j;
finished=true;
playerWon=true;
// check all Cubes
for(i=0;i<dim();i++)
{
for(j=0;j<dim();j++)
{
if(cubes[i][j]->overMax())
{
increaseNeighbours(fromWhom,i,j);
cubes[i][j]->decrease();
finished=false;
}
if(cubes[i][j]->owner()!=(Cube::Owner)fromWhom)
playerWon=false;
}
}
if(playerWon)
return true;
}
while(!finished);
return true;
}
double CubeBox::assessField(Player player) const
{
int cubesOne=0;
int cubesTwo=0;
int pointsOne=0;
int pointsTwo=0;
Player otherPlayer = ((player==One)? Two : One);
bool playerWon=true;
bool otherPlayerWon=true;
int i,j;
for(i=0;i<dim();i++)
{
for(j=0;j<dim();j++)
{
if(cubes[i][j]->owner()==(Cube::Owner)One)
{
cubesOne++;
pointsOne+=(int)pow((float)cubes[i][j]->value(),2);
}
else if(cubes[i][j]->owner()==(Cube::Owner)Two)
{
cubesTwo++;
pointsTwo+=(int)pow((float)cubes[i][j]->value(),2);
}
if(cubes[i][j]->owner()!=(Cube::Owner)player)
playerWon=false;
if(cubes[i][j]->owner()!=(Cube::Owner)otherPlayer)
otherPlayerWon=false;
}
}
if(player==One)
{
return (int)pow((float)cubesOne,2)+pointsOne-(int)pow(cubesTwo,2)-pointsTwo;
}
else
return (int)pow((float)cubesTwo,2)+pointsTwo-(int)pow(cubesOne,2)-pointsOne;
}
bool CubeBox::playerWon(Player who) const
{
int i,j;
for(i=0;i<dim();i++)
for(j=0;j<dim();j++)
{
if(cubes[i][j]->owner()!=(Cube::Owner)who)
return false;
}
return true;
}
void CubeBox::increaseNeighbours(CubeBox::Player forWhom,int row,int column)
{
Cube::Owner _player = (Cube::Owner)(forWhom);
if(row==0)
{
if(column==0) // top left corner
{
cubes[0][1]->increase(_player);
cubes[1][0]->increase(_player);
return;
}
else if(column==dim()-1) // top right corner
{
cubes[0][dim()-2]->increase(_player);
cubes[1][dim()-1]->increase(_player);
return;
}
else // top edge
{
cubes[0][column-1]->increase(_player);
cubes[0][column+1]->increase(_player);
cubes[1][column]->increase(_player);
return;
}
}
else if(row==dim()-1)
{
if(column==0) // left bottom corner
{
cubes[dim()-2][0]->increase(_player);
cubes[dim()-1][1]->increase(_player);
return;
}
else if(column==dim()-1) // right bottom corner
{
cubes[dim()-2][dim()-1]->increase(_player);
cubes[dim()-1][dim()-2]->increase(_player);
return;
}
else // bottom edge
{
cubes[dim()-1][column-1]->increase(_player);
cubes[dim()-1][column+1]->increase(_player);
cubes[dim()-2][column]->increase(_player);
return;
}
}
else if(column==0) // left edge
{
cubes[row-1][0]->increase(_player);
cubes[row+1][0]->increase(_player);
cubes[row][1]->increase(_player);
return;
}
else if(column==dim()-1) // right edge
{
cubes[row-1][dim()-1]->increase(_player);
cubes[row+1][dim()-1]->increase(_player);
cubes[row][dim()-2]->increase(_player);
return;
}
else
{
cubes[row][column-1]->increase(_player);
cubes[row][column+1]->increase(_player);
cubes[row-1][column]->increase(_player);
cubes[row+1][column]->increase(_player);
return;
}
}