head	1.26;
access;
symbols
	tonic_4:1.26
	tonic_3:1.23
	tonic_2:1.22
	demo:1.21.0.2
	design_report:1.19
	alpha_beta:1.16.0.2
	oral_presentation_freeze:1.2.0.2;
locks; strict;
comment	@ * @;


1.26
date	95.12.15.19.27.45;	author hartmans;	state Exp;
branches;
next	1.25;

1.25
date	95.12.15.19.20.53;	author jered;	state Exp;
branches;
next	1.24;

1.24
date	95.12.15.14.00.43;	author jered;	state Exp;
branches;
next	1.23;

1.23
date	95.12.15.11.25.16;	author jered;	state Exp;
branches;
next	1.22;

1.22
date	95.12.14.09.07.09;	author jered;	state Exp;
branches;
next	1.21;

1.21
date	95.12.12.23.29.04;	author hartmans;	state Exp;
branches;
next	1.20;

1.20
date	95.12.12.21.16.58;	author hartmans;	state Exp;
branches;
next	1.19;

1.19
date	95.12.11.18.49.04;	author hartmans;	state Exp;
branches;
next	1.18;

1.18
date	95.12.11.13.26.39;	author hartmans;	state Exp;
branches;
next	1.17;

1.17
date	95.12.11.11.27.16;	author jered;	state Exp;
branches;
next	1.16;

1.16
date	95.12.10.07.43.35;	author jered;	state Exp;
branches
	1.16.2.1;
next	1.15;

1.15
date	95.12.10.01.35.54;	author jered;	state Exp;
branches;
next	1.14;

1.14
date	95.12.10.01.19.41;	author jered;	state Exp;
branches;
next	1.13;

1.13
date	95.12.09.19.52.39;	author hartmans;	state Exp;
branches;
next	1.12;

1.12
date	95.12.07.23.24.21;	author jered;	state Exp;
branches;
next	1.11;

1.11
date	95.12.07.22.42.01;	author jered;	state Exp;
branches;
next	1.10;

1.10
date	95.12.07.19.09.55;	author jered;	state Exp;
branches;
next	1.9;

1.9
date	95.12.06.14.08.05;	author daveg;	state Exp;
branches;
next	1.8;

1.8
date	95.12.03.19.57.03;	author hartmans;	state Exp;
branches;
next	1.7;

1.7
date	95.12.03.05.00.08;	author hartmans;	state Exp;
branches;
next	1.6;

1.6
date	95.12.01.04.49.07;	author hartmans;	state Exp;
branches;
next	1.5;

1.5
date	95.12.01.04.30.26;	author jered;	state Exp;
branches;
next	1.4;

1.4
date	95.12.01.03.39.04;	author hartmans;	state Exp;
branches;
next	1.3;

1.3
date	95.11.30.10.21.28;	author hartmans;	state Exp;
branches;
next	1.2;

1.2
date	95.11.30.06.31.52;	author hartmans;	state Exp;
branches
	1.2.2.1;
next	1.1;

1.1
date	95.11.30.05.03.19;	author jered;	state Exp;
branches;
next	;

1.2.2.1
date	95.11.30.10.22.41;	author hartmans;	state Exp;
branches;
next	;

1.16.2.1
date	95.12.11.08.17.40;	author jered;	state Exp;
branches;
next	1.16.2.2;

1.16.2.2
date	95.12.11.11.20.23;	author jered;	state Exp;
branches;
next	1.16.2.3;

1.16.2.3
date	95.12.11.17.25.53;	author jered;	state Exp;
branches;
next	;


desc
@@


1.26
log
@Back out caching stuff
@
text
@//  This is -*- c++ -*- code


// $Id: machine_player.C,v 1.23 1995/12/15 11:25:16 jered Exp $

#include <ctype.h>
#include <6170.h>
#include <machine_player.h>
#include <ps5/url_ops.h>
#include <ps5/error_response.h>

machine_player::machine_player(long total_time, bool can_i_go) :
  player("Cyberbob",total_time) {
    // FIXME Rename the Machine Player
    can_go = can_i_go;
    my_index = -1;
}

void machine_player::display(extensions *, ostream &body, int ) const {
  string tpos;

  body << "<H3>" << get_name();
  if (get_position(tpos)) 
    body << "(" << tpos << ")";
  body << ": Time remaining(ms): " << get_time() << "<FORM METHOD=\"GET\" "
    << "ACTION=\"" << get_game()->uri_with_move() << "player/" << my_index
    << "/set_time_left\">";
  body << "<INPUT NAME=\"time\" VALUE=\"" << get_time() << "\">";
  body << "<INPUT TYPE=SUBMIT VALUE=\"Set Time\"></FORM></H3><P>" << endl;
  if (!can_go && (get_game()->get_board()->valid_move_available(my_index))) {
    body << "<A HREF=\"" << get_game()->uri_with_move() << "player/" 
      << my_index << "/make_move\">";
    body << "Make a move" << "</A><BR>";
  }
  body << "<FORM METHOD=\"GET\" ACTION=\"" << get_game()->uri_with_move() 
    << "player/" << my_index << "/set\">Can I move immediately? "
    << "<INPUT TYPE=\"RADIO\" " << "NAME=\"can_go\" VALUE=\"y\"";
  if (can_go) body << "CHECKED";
  body <<                         "> Yes <INPUT TYPE=\"RADIO\" "
    << "NAME=\"can_go\" VALUE=\"n\"";
  if (!can_go) body << "CHECKED";
  body <<                         "> No  <INPUT TYPE=\"SUBMIT\" "
    << "VALUE=\"Change Setting\"> </FORM> <BR>";
  body << "<HR>" << endl;
}

void machine_player::you_moved(move &m) {
  player::you_moved(m);
  if (can_go)
    try_move(); // Try to move anytime I can to avoid deadlocks
  // Update
}

void machine_player::opponent_moved (move &m, int p) {
  player::opponent_moved(m,p);
  if (can_go)
    try_move(); // try_move starts the clock if it can move   
}

void machine_player::state_changed(void) {
  player::state_changed();
  if (can_go)
    try_move(); // Try to move anytime I can to avoid deadlocks 
}

void machine_player::try_move(void) {
  if (!is_associated()) return;
  if (get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
    try_alpha();
  }
}

// 1-ply machine player with no time worries.
void machine_player::try_simple(void) {
  if (!is_associated()) return;
  if (get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
    move_generator *mg = get_game()->get_board()->valid_moves(my_index);
    move *cm, *tm;
    board::value cval, tval;
    check(mg->get(tm),"There were no moves from valid_moves");
    const board *b = get_game()->get_board();
    tval = b->eval_move_delta(my_index,*tm,my_index);
    while (mg->get(cm)) {
      cval = b->eval_move_delta(my_index,*cm,my_index);
      if (cval > tval) {
	tval=cval;
	tm = cm;
      }
    }
    get_game()->apply(*tm,my_index);
    delete mg;
  }
}

void machine_player::del_mgtree(mgnode *mgtop) {
  mgnode *this_mgnode = mgtop;
  mgnode *next_mgnode;
  while (this_mgnode != NULL) {
    next_mgnode=this_mgnode->next;
    delete this_mgnode->mg;
    del_mtree(this_mgnode->mn);
    delete this_mgnode;
    this_mgnode=next_mgnode;
  }
}

void machine_player::del_mtree(mnode *mtop) {
  mnode *this_mnode = mtop;
  mnode *next_mnode;
  while (this_mnode != NULL) {
    next_mnode=this_mnode->next;
    if (this_mnode->nnode != NULL)
      del_mgtree(this_mnode->nnode);
    delete this_mnode;
    this_mnode=next_mnode;
  }
}

void machine_player::try_alpha(void) {
  board * topbrd = get_game()->get_board()->clone();
  board::value inf = get_game()->get_board()->infinity;
  
  mnode *top_mnode = new mnode();
  top_mnode->nmove=NULL; top_mnode->nnode=NULL; top_mnode->next=NULL;
  board::value cval = -inf;
  move *bmove = NULL;
  move *tmove = NULL;
  long time_to_think = get_game()->get_board()->suggest_time(get_time());
  long start_time = get_time();
  long nmoves = 0;

  int curr_depth=0;
  cerr << "Time to think " << time_to_think << endl;
  while ((start_time - get_time()) < (time_to_think-nmoves)) {
//    cerr << get_time() << endl;
    nmoves = 0;
    cerr << "Starting depth " << curr_depth << "...";;
    if (!descend(top_mnode, topbrd, curr_depth, (board::value)0, cval, inf, 
		 bmove, true, NULL, start_time, time_to_think, nmoves))
      break;
    tmove=bmove;
    curr_depth++;
    if (nmoves < 2) {
      cerr << "(<2 moves at this level, bailing) ";
      break;
    }
    cerr << "found " << nmoves << " moves." << endl;
  }
cerr << endl << endl;

  if (tmove == NULL) goto stupid_bang;
  get_game()->apply(*tmove, my_index);
  del_mtree(top_mnode);  //delete everything under top_mnode
  return;

 stupid_bang:
  del_mtree(top_mnode);  //delete everything under top_mnode
//FIXME  stop_clock();
  try_simple();
}

void  machine_player::do_level(mnode *curr_mnode, board *cbrd, 
			       board::value currval, board::value &bestval, 
			       board::value maxval, move *&bestmove, 
			       move *topmove, bool istop, long &nmoves) {
  move *cmove;

  curr_mnode->nnode = new mgnode();
  mgnode *this_mgnode=curr_mnode->nnode;
  this_mgnode->mg = cbrd->valid_moves(0);
  this_mgnode->mg_index=0;
  this_mgnode->next = NULL;
  mnode *this_mnode=new mnode();
  this_mnode->next = NULL;
  this_mnode->nnode = NULL;
  this_mgnode->mn=this_mnode;
  while (this_mgnode->mg->get(cmove)) {
    nmoves++;
    board::value kval = cbrd->eval_move_delta(my_index, *cmove, 
					      this_mgnode->mg_index);
    this_mnode->next = new mnode();
    this_mnode=this_mnode->next;
    this_mnode->nmove = cmove;
    this_mnode->nval = kval;
    this_mnode->next = NULL;
    this_mnode->nnode = NULL;
    if ((currval+kval) > bestval) {
      bestval = currval+kval;
      if (istop) bestmove=cmove;
      else bestmove = topmove;
    }
#ifdef HAVE_RAND
    else if ((currval+kval) == bestval)
      if (rand() & 0x80) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
      }
#endif
    if (bestval >= maxval) return;
  }
  for (int j=1; j<get_game()->players(); j++) {
    this_mgnode->next = new mgnode();
    this_mgnode = this_mgnode->next;
    this_mgnode->mg = cbrd->valid_moves(j);
    this_mgnode->mg_index=j;
    this_mgnode->next = NULL;
    mnode *this_mnode=new mnode();
    this_mnode->next = NULL;
    this_mnode->nnode = NULL;
    this_mgnode->mn=this_mnode;
    while (this_mgnode->mg->get(cmove)) {
      nmoves++;
      board::value kval = cbrd->eval_move_delta(my_index, *cmove, 
						this_mgnode->mg_index);
      this_mnode->next = new mnode();
      this_mnode=this_mnode->next;
      this_mnode->nmove = cmove;
      this_mnode->nval = kval;
      this_mnode->next = NULL;
      this_mnode->nnode = NULL;
      if ((currval+kval) > bestval) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
      }
#ifdef HAVE_RAND
    else if ((currval+kval) == bestval)
      if (rand() & 0x80) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
      }
#endif
      if (bestval >= maxval) return;
    }
  }
//cerr << ".";
}

bool machine_player::descend(mnode *curr_mnode, board *curr_board, 
			     int this_depth, board::value currval, 
			     board::value &bval, board::value mval, 
			     move *&bmove, bool istop, move *topmove,
			     long start_time, long time_to_think,
			     long &nmoves) {

  if (this_depth==0) 
    do_level(curr_mnode, curr_board, currval, bval, mval, bmove, topmove,
	     istop, nmoves);

  mnode *this_mnode;
  mgnode *this_mgnode=curr_mnode->nnode;
  while (this_mgnode != NULL) {
    this_mnode=this_mgnode->mn->next;    // Skip first.
    while (this_mnode != NULL) {
      curr_board->apply(*(this_mnode->nmove), this_mgnode->mg_index);
      if (istop)
	descend(this_mnode, curr_board, this_depth-1, currval+
		(this_mnode->nval), bval, mval, bmove, false, 
		this_mnode->nmove, start_time, time_to_think, nmoves);
      else descend(this_mnode, curr_board, this_depth-1, currval+
		   (this_mnode->nval), bval, mval, bmove, false, topmove,
		   start_time, time_to_think, nmoves);
      if (!curr_board->unapply(*(this_mnode->nmove), this_mgnode->mg_index))
	return false;
      if (bval >= mval) return true;
      if ((start_time - get_time()) > time_to_think)
	return false;
      this_mnode= this_mnode->next;
    }
    this_mgnode = this_mgnode->next;
  }
  return true;
}
 
void machine_player::associate(game *g) {
  player::associate(g);
  my_index = get_game()->player_index(this);
}


http_response *machine_player::get (string request, extensions *ext)
{
    if (!is_associated())
	return new error_response(http_response::INTERNAL_ERROR,"Cannot send request to dissociated machine player");
    string first;
    if (unescape_uri(first_component(request), first))
	{
	    if (first == "make_move") {
		// This is somewhat of a hack but it isn't clear what
		// player is generating this request.  I.E.  Who
		// should we display the results from the point of
		// view of?  If the game only has two players, it's
		// simple: not us..  Otherwise, we go to thegame's
		// default show web request, and hope it does
		// something reasonable.
		// Consider fixing with a protoocol that contains player in the request
		if (get_game()->players() == 2) {
		    int other_pnum = (get_game()->player_index(this) == 1)?0:1;
		    try_move();
		    return get_game()->display(ext, other_pnum);
		}
		else {
		    try_move();
		    return get_game()->get("show",ext);
		}
	    }
	    if (first == "set") {
		map <string,string> *q = parse_query(extract_query(request));
		if (!q)
		    return new error_response(http_response::BAD_REQUEST,"No query string, no functionality!");
		string value;
		if (q->find("can_go",value))
		    can_go = (toupper(value[0]) == 'Y');
if (can_go)
    try_move();
		
return get_game()->get("show",ext);
		
	    }
	    else		// Add requests above this line
		return player::get(request, ext);
	}
    return player::get(request,ext);
}

@


1.25
log
@Broken stupid nonsense.
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.24 1995/12/15 14:00:43 jered Exp $
d14 1
a16 3
    top_mnode = new mnode();   // Create top node
    top_mnode->nmove=NULL; top_mnode->nnode=NULL; top_mnode->next=NULL;
    levels_cached=0;
a48 4
  if (levels_cached > 0) {
    del_level(m, my_index);
    levels_cached--;
  }
a55 4
  if (levels_cached > 0) {
    del_level(m, p);
    levels_cached--;
  }
a61 4
  del_mtree(top_mnode);      // Flush game cache
  top_mnode = new mnode();   // Replace top node
  top_mnode->nmove=NULL; top_mnode->nnode=NULL; top_mnode->next=NULL;
  levels_cached=0;
a120 13
void machine_player::del_level(move &m, int pl) {
//FIXME This should free the released levels.
  mgnode *this_mgnode=top_mnode->nnode;
  while (this_mgnode->mg_index != pl) 
    this_mgnode=this_mgnode->next;

  mnode *this_mnode=this_mgnode->mn->next;
  while (!(*(this_mnode->nmove) == m))
    this_mnode=this_mnode->next;

  top_mnode=this_mnode;
}

d125 2
d134 1
a134 5
  int curr_depth=levels_cached;
cerr << "Levels cached: " << levels_cached << endl;
  if (curr_depth > 0) 
    bmove = top_mnode->successor;

d141 1
a141 2
		 bmove, true, NULL, start_time, time_to_think, nmoves,
		 top_mnode->successor))
a144 1
    levels_cached++;
a158 1
cerr << "Bad, bad things just happened." << endl;
d167 1
a167 2
			       move *topmove, bool istop, long &nmoves,
			       move *&blev) {
a185 1
    this_mnode->successor = NULL;
a192 1
      blev = cmove;
a220 1
      this_mnode->successor = NULL;
a227 1
	blev = cmove;
d248 1
a248 1
			     long &nmoves, move *&blev, bool buildsucc) {
d252 1
a252 1
	     istop, nmoves, blev);
d263 1
a263 2
		this_mnode->nmove, start_time, time_to_think, nmoves,
		this_mnode->successor, (this_mnode->successor == NULL));
d266 1
a266 2
		   start_time, time_to_think, nmoves, this_mnode->successor,
		   (this_mnode->successor == NULL));
@


1.24
log
@Break lots of things
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.23 1995/12/15 11:25:16 jered Exp $
d285 1
a285 1
			     long &nmoves, move *&blev) {
d301 1
a301 1
		this_mnode->successor);
d304 2
a305 1
		   start_time, time_to_think, nmoves, this_mnode->successor);
@


1.23
log
@Various changes, machine player name, explicit deletion, etc. WARNING: it _may_ not be safe to delete the game tree after an unapply fails. I can't see why, though.
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.22 1995/12/14 09:07:09 jered Exp $
a13 1
    // FIXME Rename the Machine Player
d16 3
d51 4
d62 4
d72 4
d135 13
a151 2
  mnode *top_mnode = new mnode();
  top_mnode->nmove=NULL; top_mnode->nnode=NULL; top_mnode->next=NULL;
d159 5
a163 1
  int curr_depth=0;
d170 2
a171 1
		 bmove, true, NULL, start_time, time_to_think, nmoves))
d175 1
d190 1
d199 2
a200 1
			       move *topmove, bool istop, long &nmoves) {
d219 1
d227 1
d256 1
d264 1
d285 1
a285 1
			     long &nmoves) {
d289 1
a289 1
	     istop, nmoves);
d300 2
a301 1
		this_mnode->nmove, start_time, time_to_think, nmoves);
d304 1
a304 1
		   start_time, time_to_think, nmoves);
@


1.22
log
@top_node, chess_capture_move, etc fixes, machine_player speedups.
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.21 1995/12/12 23:29:04 hartmans Exp $
d13 1
a13 1
  player("Untitled Player",total_time) {
d51 1
d67 5
a71 5
    if (!is_associated()) return;
    if (get_game()->get_board()->valid_move_available(my_index)) {
	start_clock();
	try_alpha();
    }
d86 2
a87 2
	cval = b->eval_move_delta(my_index,*cm,my_index);
	if (cval > tval) {
d90 1
a90 1
	}
d97 24
d132 1
a132 1
  long nmoves;
d136 1
a136 1
  while ((start_time - get_time()) < time_to_think) {
d155 1
a155 1
  //delete everything under top_mnode
d159 1
a159 1
  //delete everything under top_mnode
d177 1
d188 1
d212 1
d223 1
@


1.21
log
@Update players so they don't display stuff that isn't needed when the other person displays them.
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.20 1995/12/12 21:16:58 hartmans Exp $
d107 1
d112 3
a114 2
    cerr << get_time() << endl;  
    cerr << "Starting depth " << curr_depth << endl;
d116 1
a116 1
		 bmove, true, NULL, start_time, time_to_think))
d120 5
a124 1
    cerr << endl;
d126 1
a126 2

cerr << endl;
d142 1
a142 1
			       move *topmove, bool istop) {
d154 1
d187 1
d211 1
a211 1
cerr << ".";
d218 2
a219 1
			     long start_time, long time_to_think) {
d223 1
a223 1
	     istop);
d234 1
a234 1
		this_mnode->nmove, start_time, time_to_think);
d237 1
a237 1
		   start_time, time_to_think);
@


1.20
log
@* game: implement message
* player: fix set_time so it works
* machine_player: move if you can when can_go is set to true
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.19 1995/12/11 18:49:04 hartmans Exp $
d19 1
a19 1
void machine_player::display(extensions *ext, ostream &body) const {
@


1.19
log
@Timing fixes, mainly for human_player
@
text
@d4 1
a4 1
// $Id: machine_player.C,v 1.18 1995/12/11 13:26:39 hartmans Exp $
d281 3
@


1.18
log
@* Add templates for rs6k;
this may break everything else.

* Fix can_go in player

* Fix set time.
@
text
@a2 1
// $Id: machine_player.C,v 1.17 1995/12/11 11:27:16 jered Exp $
d4 2
a120 1
tmove->display(NULL, cerr);
d161 8
d193 8
@


1.17
log
@Merged good new machine player.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.16.2.2 1995/12/11 11:20:23 jered Exp $
d265 2
@


1.16
log
@Fixed machine_player bogosity.
@
text
@d3 1
a3 2
// $Id: machine_player.C,v 1.15 1995/12/10 01:35:54 jered Exp $

d5 1
d96 90
a185 21
    board * topbrd = get_game()->get_board()->clone();
    board::value inf = get_game()->get_board()->infinity;
    move_generator *mg = get_game()->get_board()->valid_moves(my_index);
    move *tmove, *cmove;
    board::value cval = -inf;
    board::value tval;

    while (mg->get(tmove)) {
	topbrd->apply(*tmove,my_index);
//FIXME
	tval = alpha_beta(topbrd,topbrd->evaluate(my_index),3,-inf,inf);
	if (tval > cval) {
	    cval=tval;
	    cmove=tmove;
#ifdef HAVE_RAND
	} else if (tval == cval) {
	    if (rand() & 0x80) cmove=tmove;
#endif
	}
        if (!topbrd->unapply(*tmove,my_index))
           goto stupid_bang;
d187 2
a188 7
    get_game()->apply(*cmove,my_index);
    delete mg;
    return;

stupid_bang:
    delete mg;
    try_simple();
d191 33
a223 30
board::value machine_player::alpha_beta(board *cbrd, board::value cval, 
					int depth,  board::value min_win, 
					board::value max_win) {
// effects   Return the evaluation function of cbrd, searching
//           up to "depth" ply, where "min_win" is considered to
//           be a loss for this player and "max_win" is considered
//           to be a win for this player (i.e. no searching needs
//           be done beyond that point.)
   
    if (depth == 0) return cval;

    board::value best = min_win;
    for (int i=0; i<get_game()->players(); i++) {
	move_generator *mg = cbrd->valid_moves(i);
	
	move *cmove;
	while (mg->get(cmove)) {
	    board::value kval = cbrd->eval_move_delta(
		my_index, *cmove, i);
	    check(cbrd->apply(*cmove,i) == game::ok, "Apply failed. This "
		  "should never happen!");
	    board::value subval = alpha_beta(cbrd, cval+kval, depth-1, best,
					     max_win);
	    cbrd->unapply(*cmove,i); 
	    if (subval > best) best = subval;
	    if (best >= max_win) return max_win; // stop searching!
	}
	delete mg;
   }
    return best;
d225 1
a225 1

@


1.16.2.1
log
@Miscellany
@
text
@d3 2
a4 1
// $Id: machine_player.C,v 1.16 1995/12/10 07:43:35 jered Exp $
a5 1
#include <ctype.h>
a94 1
//FIXME Set curr_depth
d96 21
a116 52
  board * topbrd = get_game()->get_board()->clone();
  board::value inf = get_game()->get_board()->infinity;
  
  mnode *top_mnode = new mnode();
  top_mnode->nmove=NULL; top_mnode->nnode=NULL; top_mnode->next=NULL;
  board::value cval = -inf;
  move *bmove = NULL;

  int curr_depth=1;
  
  for (int i=0; i<=curr_depth; i++)
    if (!descend(top_mnode, topbrd, i, (board::value)0, cval, inf, bmove,
		 true, NULL))
      goto stupid_bang;

  get_game()->apply(*bmove, my_index);
  //delete everything under top_mnode
  return;

 stupid_bang:
  //delete everything under top_mnode
  try_simple();
}

void  machine_player::do_level(mnode *curr_mnode, board *cbrd, 
			       board::value currval, board::value &bestval, 
			       board::value maxval, move *&bestmove, 
			       move *topmove, bool istop) {
  move *cmove;

  curr_mnode->nnode = new mgnode();
  mgnode *this_mgnode=curr_mnode->nnode;
  this_mgnode->mg = cbrd->valid_moves(0);
  this_mgnode->mg_index=0;
  this_mgnode->next = NULL;
  mnode *this_mnode=new mnode();
  this_mnode->next = NULL;
  this_mgnode->mn=this_mnode;
  while (this_mgnode->mg->get(cmove)) {
    board::value kval = cbrd->eval_move_delta(my_index, *cmove, 
					      this_mgnode->mg_index);
    this_mnode->next = new mnode();
    this_mnode=this_mnode->next;
    this_mnode->nmove = cmove;
    this_mnode->nval = kval;
    this_mnode->next = NULL;
cerr << "Tried another move..." << currval+kval << endl;
    if ((currval+kval) > bestval) {
      bestval = currval+kval;
      if (istop) bestmove=cmove;
      else bestmove = topmove;
cerr << "   Found a better move!" << endl;
d118 7
a124 31
    if (bestval >= maxval) return;
  }
  for (int j=1; j<get_game()->players(); j++) {
    this_mgnode->next = new mgnode();
    this_mgnode = this_mgnode->next;
    this_mgnode->mg = cbrd->valid_moves(j);
    this_mgnode->mg_index=j;
    this_mgnode->next = NULL;
    mnode *this_mnode=new mnode();
    this_mnode->next = NULL;
    this_mgnode->mn=this_mnode;
    while (this_mgnode->mg->get(cmove)) {
      board::value kval = cbrd->eval_move_delta(my_index, *cmove, 
						this_mgnode->mg_index);
      this_mnode->next = new mnode();
      this_mnode=this_mnode->next;
      this_mnode->nmove = cmove;
      this_mnode->nval = kval;
      this_mnode->next = NULL;
cerr << "Tried another move..." << currval+kval << endl;
      if ((currval+kval) > bestval) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
cerr << "Found a better move!" << endl;
      }
      if (bestval >= maxval) return;
    }
  }
bestmove->display(NULL, cerr);
cerr << endl;
d127 30
a156 29
bool machine_player::descend(mnode *curr_mnode, board *curr_board, 
			     int this_depth, board::value currval, 
			     board::value &bval, board::value mval, 
			     move *&bmove, bool istop, move *topmove) {

  if (this_depth==0) 
    do_level(curr_mnode, curr_board, currval, bval, mval, bmove, topmove,
	     istop);

  mnode *this_mnode;
  mgnode *this_mgnode=curr_mnode->nnode;
  while (this_mgnode != NULL) {
    this_mnode=this_mgnode->mn->next;    // Skip first.
    while (this_mnode != NULL) {
      curr_board->apply(*(this_mnode->nmove), this_mgnode->mg_index);
      if (istop)
	descend(this_mnode, curr_board, this_depth-1, currval+
		(this_mnode->nval), bval, mval, bmove, false, 
		this_mnode->nmove);
      else descend(this_mnode, curr_board, this_depth-1, currval+
		   (this_mnode->nval), bval, mval, bmove, false, topmove);
      if (!curr_board->unapply(*(this_mnode->nmove), this_mgnode->mg_index))
	return false;
      if (bval >= mval) return true;
      this_mnode= this_mnode->next;
    }
    this_mgnode = this_mgnode->next;
  }
  return true;
d158 1
a158 1
 
@


1.16.2.2
log
@A working breadth-first searcher
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.16.2.1 1995/12/11 08:17:40 jered Exp $
d95 1
a103 16
  move *tmove = NULL;
  long time_to_think = get_game()->get_board()->suggest_time(get_time());
  long start_time = get_time();

  int curr_depth=0;
  cerr << "Time to think " << time_to_think << endl;
  while ((start_time - get_time()) < time_to_think) {
    cerr << get_time() << endl;  
    cerr << "Starting depth " << curr_depth << endl;
    if (!descend(top_mnode, topbrd, curr_depth, (board::value)0, cval, inf, 
		 bmove, true, NULL, start_time, time_to_think))
      break;
    tmove=bmove;
    curr_depth++;
    cerr << endl;
  }
d105 6
a110 2
tmove->display(NULL, cerr);
cerr << endl;
d112 1
a112 2
  if (tmove == NULL) goto stupid_bang;
  get_game()->apply(*tmove, my_index);
a117 1
//FIXME  stop_clock();
d143 1
d148 1
d169 1
d174 1
d179 2
a180 1
cerr << ".";
d186 1
a186 2
			     move *&bmove, bool istop, move *topmove,
			     long start_time, long time_to_think) {
d201 1
a201 1
		this_mnode->nmove, start_time, time_to_think);
d203 1
a203 2
		   (this_mnode->nval), bval, mval, bmove, false, topmove,
		   start_time, time_to_think);
a206 2
      if ((start_time - get_time()) > time_to_think)
	return false;
@


1.16.2.3
log
@A slightly more sane suggest_time.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.16.2.2 1995/12/11 11:20:23 jered Exp $
d120 1
a160 8
#ifdef HAVE_RAND
    else if ((currval+kval) == bestval)
      if (rand() & 0x80) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
      }
#endif
a184 8
#ifdef HAVE_RAND
    else if ((currval+kval) == bestval)
      if (rand() & 0x80) {
	bestval = currval+kval;
	if (istop) bestmove=cmove;
	else bestmove = topmove;
      }
#endif
@


1.15
log
@Fixed many bogosities.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.14 1995/12/10 01:19:41 jered Exp $
d140 1
a140 1
	move_generator *mg = get_game()->get_board()->valid_moves(i);
d144 1
a144 1
	    board::value kval = get_game()->get_board()->eval_move_delta(
d146 2
a147 1
	    cbrd->apply(*cmove,i);
@


1.14
log
@New machine player.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.13 1995/12/09 19:52:39 hartmans Exp $
a63 23
// 1-ply machine player with no time worries.
void machine_player::try_move(void) {
  if (!is_associated()) return;
  if (get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
    move_generator *mg = get_game()->get_board()->valid_moves(my_index);
    move *cm, *tm;
    board::value cval, tval;
    check(mg->get(tm),"There were no moves from valid_moves");
    const board *b = get_game()->get_board();
    tval = b->eval_move_delta(*tm,my_index);
    while (mg->get(cm)) {
	cval = b->eval_move_delta(*cm,my_index);
	if (cval > tval) {
	tval=cval;
	tm = cm;
	}
    }
    get_game()->apply(*tm,my_index);
    delete mg;
  }
}

d72 1
d74 3
d82 1
a82 1
    tval = b->eval_move_delta(*tm,my_index);
d84 1
a84 1
	cval = b->eval_move_delta(*cm,my_index);
d86 2
a87 2
	    tval=cval;
	    tm = cm;
d92 1
d101 1
d104 1
a104 1
	topbrd->apply(tmove);
d115 1
a115 1
        if (!topbrd->unapply(tmove))
d118 1
a118 1
    get_game()->apply(cmove,my_index);
d127 3
a129 2
board::value board::alpha_beta(board *cbrd, board::value cval, int depth, 
                               board::value min_win, board::value max_win) {
d145 2
a146 2
		my_index, cmove, i);
	    cbrd->apply(cmove);
d149 1
a149 1
	    cbrd->unapply(cmove); 
d190 1
a190 1
	    if (firrst == "set") {
@


1.13
log
@Implement set_time and set (set?can_go=foo)
Fix error in detach handling.


l
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.12 1995/12/07 23:24:21 jered Exp $
d24 5
a28 1
  body << ": Time remaining(ms): " << get_time() << "</H3><BR>" << endl;
d87 7
d95 78
@


1.12
log
@More display updates
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.11 1995/12/07 22:42:01 jered Exp $
d117 8
@


1.11
log
@Lots of display fixes and changes.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.10 1995/12/07 19:09:55 jered Exp $
d26 2
a27 2
    body << "<A HREF=\"" << get_game()->uri() << "player/" << my_index 
      << "/make_move\">";
d30 1
a30 1
  body << "<FORM METHOD=\"GET\" ACTION=\"" << get_game()->uri() 
@


1.10
log
@Improvements to machine_player and human_player display methods.
(More work to do on machine_player, will do after skating.)

Noted lots of warnings about passing strings in ...'s, is this going
to be a problem?
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.9 1995/12/06 14:08:05 daveg Exp $
d21 1
a21 2
  // I need to add a way of changing can_go.... FIXME
  body << "<H2>" << get_name();
d24 2
a25 2
  body << " Time remaining (us): " << get_time() << "</H2><P>" << endl;
  if (!can_go) {
d28 1
a28 1
    body << "Make a move" << "</A>";
d30 9
d48 2
a49 1
void machine_player::opponent_moved (move &, int ) {
d86 3
a88 3
    player::associate(g);
    my_index = get_game()->player_index(this);
	}
@


1.9
log
@added check on failed get
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.8 1995/12/03 19:57:03 hartmans Exp $
d19 13
a31 1
   body << "Hello!" << endl; // FIXME
@


1.8
log
@Fix timing in player,
add get to human_player,
fix error in game::apply
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.7 1995/12/03 05:00:08 hartmans Exp $
d47 1
a47 1
    mg->get(tm);
@


1.7
log
@Tidy up human_player,
implement machine_player::get
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.6 1995/12/01 04:49:07 hartmans Exp $
d6 1
d8 2
d28 1
a28 1
void machine_player::opponent_moved (move &m, int p) {
d48 1
a48 1
    board *b = get_game()->get_board();
d73 1
a73 1
	return new error_response(http_response::SERVER_ERROR,"Cannot send request to dissociated machine player");
d87 1
a87 1
		    int other_pnum = (get_game->player_index(this) == 1)?0:1;
d89 1
a89 1
		    return get_player()->display(ext, other_pnum);
d93 1
a93 1
		    return get_game->get("show",ext);
@


1.6
log
@Add closing brace
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.5 1995/12/01 04:30:26 jered Exp $
d65 34
@


1.5
log
@Minor optimization
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.4 1995/12/01 03:39:04 hartmans Exp $
d64 1
@


1.4
log
@Integrate oral presentation changes into main line.
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.3 1995/11/30 10:21:28 hartmans Exp $
d45 2
a46 2
    tval = get_game()->get_board()->eval_move_delta(*tm,my_index);
board *b = get_game()->get_board();
@


1.3
log
@fix machine player
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.2 1995/11/30 06:31:52 hartmans Exp $
d5 1
@


1.2
log
@Fix bugs so it builds
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.1 1995/11/30 05:03:19 jered Exp $
d11 1
a11 1
    my_index = get_game()->player_index(this);
d60 3
@


1.2.2.1
log
@And the same on this branch
@
text
@d3 1
a3 1
// $Id: machine_player.C,v 1.3 1995/11/30 10:21:28 hartmans Exp $
d11 1
a11 1
    my_index = -1;
a59 3
void machine_player::associate(game *g) {
    player::associate(g);
    my_index = get_game()->player_index(this);
@


1.1
log
@Added machine_player.{h,C}. Other minor things.
@
text
@d3 1
a3 1
// $Id$
d14 1
a14 1
void machine_player::display(extensions *ext, ostream *body) const {
d24 1
a24 1
void machine_player::opponent_moved (move &m, player *p) {
d44 2
a45 1
    tval = eval_move_delta(*tm,my_index);
d47 2
a48 2
      cval = eval_move_delta(*cm,my_index);
      if (cval > tval)
d50 2
@
