mirror of
git://git.savannah.nongnu.org/eliot.git
synced 2025-01-17 06:11:49 +01:00
Forgot these files
This commit is contained in:
parent
b102aafbcd
commit
f8074f5e02
2 changed files with 365 additions and 0 deletions
248
game/player.c
Normal file
248
game/player.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
/* Eliot */
|
||||
/* Copyright (C) 2004 Eliot */
|
||||
/* Olivier Teuliere <ipkiss@via.ecp.fr> */
|
||||
/* */
|
||||
/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* $Id: player.c,v 1.1 2004/08/07 18:25:03 ipkiss Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dic.h"
|
||||
#include "tiles.h"
|
||||
#include "rack.h"
|
||||
#include "pldrack.h"
|
||||
#include "round.h"
|
||||
#include "results.h"
|
||||
#include "board.h"
|
||||
#include "player.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
struct tplayer {
|
||||
int human;
|
||||
int score;
|
||||
play_status status; /* Only used for duplicate mode currently */
|
||||
|
||||
/* History of the racks and rounds for the player */
|
||||
int nracks;
|
||||
Playedrack racks[PLAYEDRACK_MAX];
|
||||
Round rounds[PLAYEDRACK_MAX];
|
||||
int turns[PLAYEDRACK_MAX];
|
||||
|
||||
/* Results of a search with the current rack */
|
||||
Results searchresults;
|
||||
};
|
||||
|
||||
|
||||
Player
|
||||
Player_create(void)
|
||||
{
|
||||
int i;
|
||||
Player p;
|
||||
p = (Player) malloc(sizeof(struct tplayer));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < PLAYEDRACK_MAX; i++)
|
||||
{
|
||||
p->racks[i] = Playedrack_create();
|
||||
p->rounds[i] = Round_create();
|
||||
}
|
||||
p->searchresults = Results_create();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Player_init(Player p, int human)
|
||||
{
|
||||
int i;
|
||||
|
||||
p->score = 0;
|
||||
p->human = human;
|
||||
p->status = TO_PLAY;
|
||||
p->nracks = 0;
|
||||
for (i = 0; i < PLAYEDRACK_MAX; i++)
|
||||
{
|
||||
Playedrack_init(p->racks[i]);
|
||||
Round_init(p->rounds[i]);
|
||||
}
|
||||
Results_init(p->searchresults);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Player_inithuman(Player p)
|
||||
{
|
||||
Player_init(p, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Player_initai(Player p)
|
||||
{
|
||||
Player_init(p, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Player_destroy(Player p)
|
||||
{
|
||||
int i;
|
||||
if (p)
|
||||
{
|
||||
for (i = 0; i < PLAYEDRACK_MAX; i++)
|
||||
{
|
||||
Playedrack_destroy(p->racks[i]);
|
||||
Round_destroy(p->rounds[i]);
|
||||
}
|
||||
Results_destroy(p->searchresults);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Playedrack
|
||||
Player_getplayedrack(Player p)
|
||||
{
|
||||
return p->racks[p->nracks];
|
||||
}
|
||||
|
||||
|
||||
Playedrack
|
||||
Player_getlastrack(Player p)
|
||||
{
|
||||
return p->racks[p->nracks - 1];
|
||||
}
|
||||
|
||||
|
||||
Round
|
||||
Player_getlastround(Player p)
|
||||
{
|
||||
return p->rounds[p->nracks - 1];
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Player_getpoints(Player p)
|
||||
{
|
||||
return p->score;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Player_addpoints(Player p, int s)
|
||||
{
|
||||
p->score += s;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Player_setstatus(Player p, play_status stat)
|
||||
{
|
||||
p->status = stat;
|
||||
}
|
||||
|
||||
|
||||
play_status
|
||||
Player_getstatus(Player p)
|
||||
{
|
||||
return p->status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function increments the number of racks, and fills the new rack
|
||||
* with the unplayed tiles from the previous one.
|
||||
* 03 sept 2000 : We have to sort the tiles according to the new rules
|
||||
*/
|
||||
void
|
||||
Player_endturn(Player p, Round round, int turn)
|
||||
{
|
||||
tile_t i;
|
||||
Rack rack;
|
||||
|
||||
p->turns[p->nracks] = turn;
|
||||
Round_copy(p->rounds[p->nracks], round);
|
||||
|
||||
/* Increment the number of racks
|
||||
* We are now going to deal with p->racks[p->nracks - 1] and
|
||||
* p->racks[p->nracks] */
|
||||
p->nracks++;
|
||||
|
||||
rack = Rack_create();
|
||||
Playedrack_getrack(p->racks[p->nracks - 1], rack);
|
||||
|
||||
/* We remove the played tiles from the rack */
|
||||
for (i = 0; i < Round_wordlen(round); i++)
|
||||
{
|
||||
if (Round_playedfromrack(round, i))
|
||||
{
|
||||
if (Round_joker(round,i))
|
||||
Rack_remove(rack, (tile_t)JOKER_TILE);
|
||||
else
|
||||
Rack_remove(rack, Round_gettile(round, i));
|
||||
}
|
||||
}
|
||||
|
||||
Playedrack_init(p->racks[p->nracks]);
|
||||
Playedrack_setold(p->racks[p->nracks], rack);
|
||||
Rack_destroy(rack);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Player_ai(Player p)
|
||||
{
|
||||
return ! p->human;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Player_ai_search(Player p, Dictionary dic, Board board, int turn)
|
||||
{
|
||||
Rack rack;
|
||||
if (dic == NULL)
|
||||
return 1;
|
||||
|
||||
Results_init(p->searchresults);
|
||||
|
||||
rack = Rack_create();
|
||||
Playedrack_getrack(p->racks[p->nracks], rack);
|
||||
if (turn == 0)
|
||||
Board_search_first(dic, board, rack, p->searchresults);
|
||||
else
|
||||
Board_search(dic, board, rack, p->searchresults);
|
||||
Rack_destroy(rack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Round
|
||||
Player_ai_bestround(Player p)
|
||||
{
|
||||
return Results_get(p->searchresults, 0);
|
||||
}
|
||||
|
||||
|
||||
Results
|
||||
Player_ai_getresults(Player p)
|
||||
{
|
||||
return p->searchresults;
|
||||
}
|
||||
|
117
game/player.h
Normal file
117
game/player.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* Eliot */
|
||||
/* Copyright (C) 2004 Eliot */
|
||||
/* Olivier Teuliere <ipkiss@via.ecp.fr> */
|
||||
/* */
|
||||
/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* $Id: player.h,v 1.1 2004/08/07 18:25:03 ipkiss Exp $ */
|
||||
|
||||
#ifndef _PLAYER_H_
|
||||
#define _PLAYER_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Number of played words.
|
||||
* There are only 102 tiles, so we should be safe even if only one tile is
|
||||
* played at each turn... */
|
||||
#define PLAYEDRACK_MAX 102
|
||||
|
||||
/*************************
|
||||
* A player can be a human player, or a computer player (AI)
|
||||
*************************/
|
||||
|
||||
typedef struct tplayer *Player;
|
||||
|
||||
/*************************
|
||||
* Player general routines
|
||||
*************************/
|
||||
|
||||
Player Player_create (void);
|
||||
void Player_inithuman (Player);
|
||||
void Player_initai (Player);
|
||||
void Player_destroy (Player);
|
||||
|
||||
/**************************
|
||||
* General getters
|
||||
**************************/
|
||||
|
||||
Playedrack Player_getplayedrack (Player);
|
||||
Playedrack Player_getlastrack (Player);
|
||||
Round Player_getlastround (Player);
|
||||
|
||||
/**************************
|
||||
*
|
||||
**************************/
|
||||
|
||||
void Player_endturn (Player,Round,int);
|
||||
|
||||
/**************************
|
||||
* Add (or remove, if the given value is negative) points
|
||||
* to the player's score.
|
||||
**************************/
|
||||
|
||||
void Player_addpoints (Player,int);
|
||||
int Player_getpoints (Player);
|
||||
|
||||
/**************************
|
||||
*
|
||||
**************************/
|
||||
|
||||
typedef enum {PLAYED, TO_PLAY} play_status;
|
||||
void Player_setstatus (Player,play_status);
|
||||
play_status Player_getstatus (Player);
|
||||
|
||||
/**************************
|
||||
* AI (Artificial Intelligence) handling
|
||||
* The int argument of Player_ai_search() is the 'turn' number
|
||||
* (starting from 0)
|
||||
* Note: we could implement various strategies:
|
||||
* - best: play the word with the best score (current implementation)
|
||||
* - second: play the word with the second best score (strictly lower than
|
||||
* the best one)
|
||||
* - random: randomly choose one of the possible words
|
||||
* - handicap(p): in the array of the n possible words (sorted by
|
||||
* decreasing scores), play the word number i, where i/n is nearest
|
||||
* from a predefined percentage p.
|
||||
* So 'handicap(0)' should be equivalent to 'best'.
|
||||
* This strategy makes an interesting opponent, because you can adapt
|
||||
* it to your level, with a careful choice of the p value.
|
||||
*
|
||||
* In fact, instead of working on the score of the words, these strategies
|
||||
* could work on any other value. In particular, some heuristics could
|
||||
* modulate the score with a value indicating the openings offered by the
|
||||
* word (if a word makes accessible a "word counts triple" square, it is less
|
||||
* interesting than another word with the same score or even with a slightly
|
||||
* lower score, but which does not offer such a square).
|
||||
*
|
||||
* More evolved heuristics could even take into account the remaining letters
|
||||
* in the bag to guess the 'statistical rack' of the opponent, and play a
|
||||
* word both maximizing the score and minimizing the opponent's score...
|
||||
* Hmmm... i don't think this one will be implemented in a near future :)
|
||||
**************************/
|
||||
|
||||
int Player_ai (Player);
|
||||
int Player_ai_search (Player,Dictionary,Board,int);
|
||||
Round Player_ai_bestround (Player); // XXX: useful?
|
||||
Results Player_ai_getresults (Player);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in a new issue