PraktikumOthello/players/playerlib.cc

334 lines
8.6 KiB
C++

//#define debugprint
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "playerlib.h"
//determines whether move or not and adds them to a movesList
int fillMovesList(cell (*)[fieldSize], movesList *, size_t, size_t, unsigned int *, unsigned int *, char);
int iterDiagForwards(cell (*)[fieldSize], movesList *, size_t, size_t, char);
int iterDiagBackwards(cell (*)[fieldSize], movesList *, int, int, char);
//adds all hotizontally-forward found moves to movesList
int findHorizontalForwardMoves(cell (*)[fieldSize], movesList *, char);
int findHorizontalBackwardMoves(cell (*)[fieldSize], movesList *, char);
int findVerticalForwardMoves(cell (*)[fieldSize], movesList *, char);
int findVerticalBackwardMoves(cell (*)[fieldSize], movesList *, char);
int findDiagonalTopLeftMoves(cell (*)[fieldSize], movesList *, char);
int findDiagonalBottomRightMoves(cell (*)[fieldSize], movesList *, char);
int findDiagonalBottomLeftMoves(cell (*)[fieldSize], movesList *, char);
int findDiagonalTopRightMoves(cell (*)[fieldSize], movesList *, char);
unsigned int endgame=0;
char
getEnemyChar(char c) {
char enemyc;
switch(c)
{
case 'X':
enemyc='O'; break;
case 'O':
enemyc='X'; break;
}
return enemyc;
}
int
readStateBuffer(char *stateBuffer, struct cell (*gameField)[fieldSize], unsigned int *numX, unsigned int *numO) {
for(size_t row=0; row < fieldSize; ++row)
{
for(size_t col=0; col< fieldSize; ++col)
{
int index = row*fieldSize+col+1;
gameField[row][col].content = stateBuffer[index];
if (stateBuffer[index] == 'X')
++(*numX);
if (stateBuffer[index] == 'O')
++(*numO);
#ifdef debugprint
//printf("gameField %lu %lu =stateBuffer %d = %c\n", row, col, index, gameField[row][col].content);
#endif
}
}
return 0;
}
int
fillMovesList(cell (*field)[fieldSize], movesList *moves, size_t row, size_t col, unsigned int *ownCount, unsigned int *enemyCount, char enemyc) {
++(field[row][col].timesVisited);
char ownc = getEnemyChar(enemyc);
if (field[row][col].content == ownc)
{
++(*ownCount);
*enemyCount = 0;
#ifdef debugprint
printf("%d,%d: ownCount: %d, enemyCount: %d\n", row, col, *ownCount, *enemyCount);
#endif
}
if(field[row][col].content == enemyc && ownCount)
{
++(*enemyCount);
#ifdef debugprint
printf("%d,%d: ownCount: %d, enemyCount: %d\n", row, col, *ownCount, *enemyCount);
#endif
}
if(field[row][col].content == '.')
{
if (*ownCount && *enemyCount > 0)
{
#ifdef debugprint
printf("MOVE!\n");
#endif
moves->list[moves->movesNumber].turnRow = row+1;
moves->list[moves->movesNumber].turnCol = col+1;
++(moves->movesNumber);
}
*ownCount = 0;
*enemyCount = 0;
#ifdef debugprint
printf("%d,%d: ownCount: %d, enemyCount: %d\n", row, col, *ownCount, *enemyCount);
#endif
}
return 0;
}
int
findHorizontalForwardMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (size_t row = 0;row < fieldSize; ++row)
{
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (size_t col = 0;col < fieldSize; ++col)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
return 0;
}
int
findHorizontalBackwardMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (int row = 7; row >= 0; --row)
{
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (int col = 7; col >= 0; --col)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
return 0;
}
int
findVerticalForwardMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (size_t col = 0;col < fieldSize; ++col)
{
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (size_t row = 0;row < fieldSize; ++row)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
return 0;
}
int
findVerticalBackwardMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (int col = 7; col >= 0; --col)
{
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (int row = 7; row >= 0; --row)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
return 0;
}
int
iterDiagForwards(cell (*field)[fieldSize], movesList *moves, size_t row, size_t col, char enemyc) {
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (; row < fieldSize && col < fieldSize; ++row, ++col)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
#ifdef debugprint
//printf("%d,%d\n", row,col);
#endif
}
return 0;
}
int
iterDiagBackwards(cell (*field)[fieldSize], movesList *moves, int row, int col, char enemyc) {
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount = 0, enemyCount = 0;
for (; row >= 0 && col >= 0; --row, --col)
{
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
#ifdef debugprint
//printf("%d,%d\n", row,col);
#endif
}
return 0;
}
int
findDiagonalBottomRightMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (size_t col = 0; col < fieldSize; ++col)
{
#ifdef debugprint
printf("F%d\n",col);
printf("\n---------------------------------\n");
#endif
iterDiagForwards(field, moves, 0, col, enemyc);
if(col != 0)
{
//2. Mal aufrufen, da Matrix symmetrisch zu transponierter (?)
#ifdef debugprint
printf("\n---------------------------------\n");
#endif
iterDiagForwards(field, moves, col, 0, enemyc);
}
}
return 0;
}
int
findDiagonalTopLeftMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for (int col = fieldSize-1; col >= 0; --col)
{
#ifdef debugprint
printf("F%d\n",col);
printf("\n---------------------------------\n");
#endif
iterDiagBackwards(field, moves, fieldSize-1, col, enemyc);
if(col != fieldSize-1)
{
#ifdef debugprint
printf("\n---------------------------------\n");
#endif
iterDiagBackwards(field, moves, col, fieldSize-1, enemyc);
}
}
return 0;
}
int
findDiagonalBottomLeftMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for(int i=0; i<fieldSize; ++i)
{
#ifdef debugprint
printf("\n---------------------------------\n");
#endif
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount=0, enemyCount=0;
for(int row=0; row<= i && row < fieldSize; ++row)
{
int col = i-row;
#ifdef debugprint
printf("%d %d\n", row, col);
#endif
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
for(int i=fieldSize; i<2*fieldSize-1; ++i)
{
#ifdef debugprint
printf("i=%d\n", i);
printf("\n---------------------------------\n");
#endif
unsigned int ownCount=0, enemyCount=0;
int col=7;
int row= i-col;
while(row < fieldSize-1)
{
row= i-col;
#ifdef debugprint
printf("%d %d\n", row, col);
#endif
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
col--;
}
//letzte "Diagonale" hätte Länge 1, kann keinen Zug enthalten
}
return 0;
}
int
findDiagonalTopRightMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
for(int i=2*fieldSize-2; i>=fieldSize; --i)
{
#ifdef debugprint
printf("i=%d\n", i);
printf("\n---------------------------------\n");
#endif
unsigned int ownCount=0, enemyCount=0;
int row=7;
int col= i-row;
while(col<fieldSize-1)
{
col= i-row;
#ifdef debugprint
printf("%d %d\n", row, col);
#endif
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
row--;
}
}
for(int i=fieldSize-1; i>=0; --i)
{
#ifdef debugprint
printf("\n---------------------------------\n");
#endif
//Anzahl eigener/gegnerischer Steine
unsigned int ownCount=0, enemyCount=0;
for(int col=0; col<=i; ++col)
{
int row = i-col;
#ifdef debugprint
printf("%d %d\n", row, col);
#endif
fillMovesList(field, moves, row, col, &ownCount, &enemyCount, enemyc);
}
}
return 0;
}
int
findMoves(cell (*field)[fieldSize], movesList *moves, char enemyc) {
return findHorizontalForwardMoves(field, moves, enemyc) +
findHorizontalBackwardMoves(field, moves, enemyc) +
findVerticalForwardMoves(field, moves, enemyc) +
findVerticalBackwardMoves(field, moves, enemyc) +
findDiagonalBottomRightMoves(field, moves, enemyc) +
findDiagonalTopLeftMoves(field, moves, enemyc) +
findDiagonalBottomLeftMoves(field, moves, enemyc) +
findDiagonalTopRightMoves(field, moves, enemyc);
}
int
isCornerField(move m) {
if( (m.turnRow == 1 || m.turnRow == fieldSize) && (m.turnCol == 1 || m.turnCol == fieldSize) )
return 1;
return 0;
}
int
isCOrXField(move m) {
if( ((m.turnCol == 1 || m.turnCol == fieldSize) && (m.turnRow == 2 || m.turnRow == fieldSize-1)) ||
((m.turnCol == 2 || m.turnCol == fieldSize-1) && (m.turnRow == 1 || m.turnRow == 2 || m.turnRow == fieldSize || m.turnRow == fieldSize-1)) )
return 1;
return 0;
}