head	1.36;
access;
symbols
	tonic_4:1.36
	tonic_3:1.36
	tonic_2:1.36
	demo:1.35.0.2
	design_report:1.30
	oral_presentation_freeze:1.10.0.2
	DAVEG_CDP:1.7.0.4
	template_integ:1.7.0.2;
locks; strict;
comment	@ * @;


1.36
date	95.12.15.08.12.15;	author hartmans;	state Exp;
branches;
next	1.35;

1.35
date	95.12.13.03.30.16;	author daveg;	state Exp;
branches;
next	1.34;

1.34
date	95.12.12.23.58.37;	author daveg;	state Exp;
branches;
next	1.33;

1.33
date	95.12.12.23.29.01;	author hartmans;	state Exp;
branches;
next	1.32;

1.32
date	95.12.12.21.16.55;	author hartmans;	state Exp;
branches;
next	1.31;

1.31
date	95.12.12.14.38.44;	author hartmans;	state Exp;
branches;
next	1.30;

1.30
date	95.12.11.21.08.38;	author daveg;	state Exp;
branches;
next	1.29;

1.29
date	95.12.11.20.45.30;	author jered;	state Exp;
branches;
next	1.28;

1.28
date	95.12.11.20.39.25;	author hartmans;	state Exp;
branches;
next	1.27;

1.27
date	95.12.11.19.28.02;	author jered;	state Exp;
branches;
next	1.26;

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

1.25
date	95.12.11.08.50.33;	author rgmisra;	state Exp;
branches;
next	1.24;

1.24
date	95.12.11.07.09.33;	author hartmans;	state Exp;
branches;
next	1.23;

1.23
date	95.12.10.09.55.13;	author hartmans;	state Exp;
branches;
next	1.22;

1.22
date	95.12.10.05.14.26;	author hartmans;	state Exp;
branches;
next	1.21;

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

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

1.19
date	95.12.06.14.11.26;	author daveg;	state Exp;
branches;
next	1.18;

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

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

1.16
date	95.12.04.05.00.10;	author jered;	state Exp;
branches;
next	1.15;

1.15
date	95.12.03.19.57.01;	author hartmans;	state Exp;
branches;
next	1.14;

1.14
date	95.12.03.01.17.49;	author hartmans;	state Exp;
branches;
next	1.13;

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

1.12
date	95.12.01.04.50.14;	author hartmans;	state Exp;
branches;
next	1.11;

1.11
date	95.12.01.03.39.03;	author hartmans;	state Exp;
branches;
next	1.10;

1.10
date	95.11.30.06.31.51;	author hartmans;	state Exp;
branches
	1.10.2.1;
next	1.9;

1.9
date	95.11.30.04.26.48;	author hartmans;	state Exp;
branches;
next	1.8;

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

1.7
date	95.11.22.07.37.13;	author daveg;	state Exp;
branches;
next	1.6;

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

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

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

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

1.2
date	95.11.20.06.21.02;	author hartmans;	state Exp;
branches;
next	1.1;

1.1
date	95.11.20.00.52.39;	author hartmans;	state Exp;
branches;
next	;

1.10.2.1
date	95.11.30.08.33.52;	author hartmans;	state Exp;
branches;
next	1.10.2.2;

1.10.2.2
date	95.11.30.09.44.53;	author hartmans;	state Exp;
branches;
next	;


desc
@Non-display oriented game stuff
@


1.36
log
@set_time_left is happy now
@
text
@// Implementation of class game
// $Id: game.C,v 1.35 1995/12/13 03:30:16 daveg Exp $

#include <6170.h>
#include <stdio.h>

#include <game.h>
#include <player.h>
#include <move.h>
#include <board.h>
#include <6170.h>
#include <ps5/error_response.h>
#include <ps5/url_ops.h>
#include <chess_capture_move.h>
#include <antichess_board.h>
#include <ps5/expired_response.h>
game::game (board *b_in, player *p1_in, player *p2_in, string uri_in, 
	    string image_uri_in, bool p1_is_def_in):history(50)
{
  p1 = p1_in;
  p2 = p2_in;
  b = b_in;
  my_uri = uri_in;
  image_uri = image_uri_in;
  p1_is_def = p1_is_def_in;
  win = -1;
  b->associate(this);
  p1->associate(this);
  p2->associate(this);
  state_changed();
}

game::~game() {
  delete p1;
  p1 = 0;
  delete p2;
  p2 = 0;
  delete b;
  b = 0;
}

class history_gen : public generator <move *> {
public:

    history_gen(const array <move *> *history);
    // Effects: constructs a generator that returns the moves starting
    // at history[0] and until history[length()-1].  If history has
    // length 0, the the generator is initially empty.

    bool get(move *&m);
    // Modifies: this
    // Effects:  If more moves remain, returns true and sets m to be a pointer
    //  to the next move, else returns false.

private:
    int index;
    const array <move *> *a;
};

history_gen::history_gen (const array <move *> *history) {
  index = 0;
  a = history;
}

bool history_gen::get (move *&m) {
  if ( index == a->length())
    return false;
  
  m = a->fetch(index++);
  return true;
}

generator <move *> *game::move_history() const {
  return new history_gen(&history);
}

bool game::get_move (int number, move *&m) const {
  if ( (number < 0) || (number >= history.length()))
    return false;
  m = history[number];
  return true;
}

game::move_result game::apply (move &m, int p) {
check ((p >= 0)&&(p < players()), "player out of range");
  player *otherp = (p == 0)?p2:p1;
  if (win != -1)
      return game_already_done;

  move_result res = b->apply(m, p);
  switch (res) {
  case ok:
      history.append(m.copy());
      get_player(p)->you_moved(m);
      otherp->opponent_moved(m, p);
      break;

  case move_invalid: {
      strstream ts;
      ts<<"Invalid move: ";
      m.display(0,ts);
      message(ts.str());
  }      
      break;
      
  default:;
    // Do nothing, I guess	
    
    // Do something if necessary
  }
int pwinning;
  
  if ((pwinning = b->winner()) != -1)
    win = pwinning;
  return res;
  
}

int game::winner() const {
return win;
}

void game::forfeit (int p) {
  check ((p == 0)||(p == 1), "player forfeits but not actually a player");
  check ( win != p, "Winner wants to forfeit.");
  if (p == 0)
    win = 1;
  else win = 0;
}

void game::state_changed() {
  p1->state_changed();
  p2->state_changed();
}

http_response *game::ref_move(string smove, extensions *ext) {

    chess_capture_move m;

    antichess_board *cb = (antichess_board *)b->
	force(antichess_board::typeinfo);
    
    if (!stomove(smove, m, cb))
	return new error_response(http_response::BAD_REQUEST,
				  "Bad Ref");
    int p;
    if (p1_is_def)
	p = 0;
    else
	p = 1;
    if (apply(m, p) == move_invalid)
	return new error_response(http_response::BAD_REQUEST,
				  "Bad Ref");
    return ref_display(ext);
}

http_response *game::ref_display(extensions* ext) {
    
    class ref_response: public expired_response {
	// Overview: Produces a http response giving the
	// current state of the game, players and board.
      public:
	ref_response(bool p1_is_def_in,
		     const game *gm, extensions *texts):
	expired_response(true) {
	    g=gm;
	    exts=texts;
	    p1_is_def = p1_is_def_in;
	}

	virtual void body (ostream &os){
	    os << last_component(g->uri()) << endl;
				// We print the name of the
				// non-default player, because in
				// ref_newgame, the default player is
				// selected to be the tournament
				// player.
	    if (p1_is_def)
		os << g->get_player(1)->get_name()<<endl;
	    else os << g->get_player(0)->get_name()<<endl;
	    
	    if (g->number_moves() == 0)
		os << "started\n";
	    else if (g->winner()== (p1_is_def?0:1)) {
		os << "yield\n"; // we lost
		    }
	    else {
		move *m;
		check(g->get_move(g->number_moves()-1, m),"couldn't get last move");
		m->display(exts, os);
	    }	    
	    int time = g->get_player(0)->get_time();
	    if (time < 0)
		time = 0;
	    os << time << " ";
	    time = g->get_player(1)->get_time();
	    if (time < 0)
		time = 0;
	    os << time << "\n";
	}    
      
      private:
	const game *g;
	extensions *exts;
	bool p1_is_def;
    };

    return new ref_response(p1_is_def, this, ext);
}


http_response *game::get(string request, extensions *ext) {
    string first;
    if (!unescape_uri(first_component(request), first))
	return new error_response(http_response::BAD_REQUEST,
				  "<strong> Your request is malformed.</strong>");
    if (first == "display") {
	map <string, string> *q = parse_query(extract_query(request));
	string player_num_s;
	if (q&&q->find("player", player_num_s)) {
	    int pnum = atoi(player_num_s.get_chars());
	    if ( (0 <= pnum) && (pnum < players())) 
		return display(ext, pnum);
	    else return new error_response(http_response::BAD_REQUEST, "You included an invalid player number in a display request.");
	}
	else return new error_response(http_response::BAD_REQUEST,
				       "Sorry, but display requires a player number.");
    }
    else if (first == "show"){
	if (p1_is_def)
	    return get("display?player=0",ext);
	else return get("display?player=1",ext);
    }
    else if (first =="move" ) {
	map <string, string> *q = parse_query(extract_query(request));
	if (!q) 
	    return new error_response(http_response::BAD_REQUEST,
				      "Your request should include a query string.");
	chess_capture_move m;
	string s;
	antichess_board *ab = (antichess_board *)get_board()->
	    force(antichess_board::typeinfo);
	
	if (q->find("move", s) && stomove(s,m,ab))
	    if ( apply(m,p1_is_def?0:1) == move_invalid)
		message("Invalid move.");
	return get("show", ext);
    }
    else if (first == "opponent_move") {
	if (p1_is_def)
	    return get_player(1)->get("make_move",ext);
	else return get_player(0)->get("make_move",ext);
    }
    else if (first  == "yield" ) {
	if (p1_is_def)
	    return p1->get("forfeit", ext);
	else return p2->get("forfeit", ext);
    }
    else if (first == "detach") {
	// Because of the spec, this goes to the non-default player.
	if (!p1_is_def)
	    return p1->get("detach", ext);
	else return p2->get("detach", ext);
    }
    else if (first == "attach") {
	// We pass it off  to p1 then p2; if neither succeeds then we return an error.
	http_response *hr;
	hr = p1->get(string("attach?")+extract_query(request),ext);
	if (hr->code() == http_response::OK)
	    return hr;
	return p2->get(string("attach?")+extract_query(request),ext);
    }
    
    else if (first == "ref_move"){
	string pmove;
	map <string, string> *q = parse_query(extract_query(request));
	if (q&&q->find("move", pmove))
	    return ref_move(pmove, ext);
	else return new error_response(http_response::BAD_REQUEST,
				       "Bad Ref");
    }
    else if (first == "set_time_left") {
	map <string,string> *q = parse_query(extract_query(request));
	string tmp;
	if (q&&q->find("btime", tmp)){ 
	    int timel = atoi(tmp.get_chars());
	    if (timel > 0)
		p2->set_time(timel);
	}
	if (q && q->find("wtime", tmp)) {
	    int timel = atoi(tmp.get_chars());
	    if (timel > 0 )
		p1->set_time(timel);
	}
	return new normal_response(false);
    }
    else {
				//  OK, that had better be a move number.
	request = rest_components(request);
	string dest = first_component(request);
	int movenum = atoi(first.get_chars());
	if ( movenum !=number_moves()) {
	    class out_of_sync_response: public normal_response {
		// Overview: Produces a http response indicating that
		// the browser has gotten out of sync with the game
		// and giving a link to resync.
	    public:
		out_of_sync_response(int mn, string req, game *gm):
		    normal_response(true)
		{
		    movenum = mn;
		    request = req;
		    g = gm;
		}

		virtual void body (ostream &os){
		    os << "<html> <head>\n";
		    os << "<title> Out of sync: move "<< movenum <<" not "<<
			g->number_moves()<<"</title></head>\n";
		    os << "<body> <h1> Your web browser is out of sync.</h1>\n";
		    os <<"<p> Your web browser is out of sync with the game.\n";
		    os <<" Instead of being at move "<<g->number_moves()<<
			" you sent a request from the move "<<movenum<<
			"board.  You can try and <a href=\"";
		    os<<g->uri()<<g->number_moves()<<"/"<<request
		      <<
			"\"> resyncing</a>.</body></html>\n";
		}

	    private:
game *g;
		string request;
		int movenum;
	    };
	    return new out_of_sync_response(movenum,request,this);
	}
	if ( dest == "board")
	    return b->get(rest_components(request), ext);
	else if (dest == "player") {
	    request = rest_components(request); // Throw away player destination tag
	    string pnum_s = first_component(request);
	    int playernum = atoi(pnum_s.get_chars());
	    if ((playernum >= 0)&&(playernum < players()))
		return get_player(playernum)->get(rest_components(request),ext);
	    else return new error_response(http_response::NOT_FOUND,
					   " The selected player is out of range");
	}
	// Add additional requests above this point
	return new error_response(http_response::NOT_FOUND, "The requested object could not be found.");
    }
    return new error_response(http_response::BAD_REQUEST,
			      "Game requests in the new protocol must have a move number or be display.");
}
    


void game::message(string s) {
msgarray.append(s);
}

http_response *game::display(extensions* ext, int player_num) const {
  class game_response: public expired_response {
    // Overview: Produces a http response giving the
    // current state of the game, players and board.
  public:
    game_response(int mn, const game *gm, extensions *texts, int playn, const array <string> &messages):
	expired_response(true) ,
	msg(messages)
      {
      movenum=mn;
      g=gm;
      exts=texts;
      pnum=playn;
    }

    virtual void body (ostream &os){
      move *lastmove;

      os << "<HTML> <HEAD>" << endl;
      os << "<TITLE> Game: Move Number " << movenum << "</TITLE> </HEAD>"
	 << endl;
      os << "<BODY><H1>Game: Move Number " << movenum << "</H1><P>" << endl;
      if (g->number_moves() != 0) {
	  check(g->get_move(g->number_moves()-1,lastmove),
		"Unable to get last move");
	os << "Last move: ";
	lastmove->display(exts, os);
      }
      if (msg.length() > 0) {
	  os <<"<h2> Messages</h2><ul>"<<endl;
	  for (int lc = msg.length()-1; (lc > 0)&&(msg.length()-lc < 3); lc--)
	      os <<"<li> "<<msg[lc]<<"</li>\n";
	  os <<"</ul>\n";
      }
      
      g->get_board()->display(exts, os, pnum);
      for (int i=0; i<g->players(); i++) {
	g->get_player(i)->display(exts, os, pnum); 
	os << "<P>"; }
      os << "<a href=\"/welcome\">Back to the top</a>\n";
      os << "<HR><ADDRESS>6.170-team1@@mit.edu</ADDRESS>" << endl;
      os << "</BODY></HTML>";
    }
    
  private:
    const game *g;
    extensions *exts;
    int pnum;
    int movenum;
const array <string> msg;
      
};
    return new game_response(number_moves(), this, ext, player_num,msgarray);
}


int game::player_index(const player *p ) const {
    if (p == p1 )
	return 0;
    else if (p == p2)
	return 1;
    else return -1;
}



int game::number_moves() const {
    return history.length();
}


string game::uri_with_move() const
{
  char buf[30];
  sprintf(buf, "%u", number_moves());
  return uri()+buf+"/";
}

@


1.35
log
@bug fix
@
text
@d2 1
a2 1
// $Id: game.C,v 1.34 1995/12/12 23:58:37 daveg Exp $
d282 15
a296 1
    
@


1.34
log
@finished ref_*
@
text
@d2 1
a2 1
// $Id: game.C,v 1.33 1995/12/12 23:29:01 hartmans Exp $
d15 1
a15 1
#include <chess_display_board.h>
d137 1
d139 5
a143 1
    if (!stomove(smove, m, b))
d184 1
a184 1
	    else if (g->winner()== p1_is_def?0:1) {
d241 4
a244 1
	if (q->find("move", s) && stomove(s,m,get_board()))
@


1.33
log
@Update players so they don't display stuff that isn't needed when the other person displays them.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.32 1995/12/12 21:16:55 hartmans Exp $
d83 1
a83 1
#include <antichess_board.h>
a89 2
antichess_board *ab = (antichess_board *)b->force(antichess_board::typeinfo);

a92 1
      ab->save(cout);
a94 1
      ab->save(cout);
d97 1
d99 1
a99 1
strstream ts;
d136 13
a148 3

http_response *game::ref_game(extensions *ext) {
    //p1->state_changed();
d163 2
a164 2
p1_is_def = p1_is_def_in;
      }
d200 1
a200 1
bool p1_is_def;
d264 9
@


1.32
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
@d2 1
a2 1
// $Id: game.C,v 1.31 1995/12/12 14:38:44 hartmans Exp $
d360 1
a360 1
	g->get_player(i)->display(exts, os); 
@


1.31
log
@In misc, insert destructor for chess_capture_move
Game: fix up ref_response and
display of last move.

Fix up bug in handling of first component to game::get that prevents
display and can_go and others from working.

  CVS:
----------------------------------------------------------------------
automatically CVS: CVS: Committing in base CVS: CVS: Modified Files:
----------------------------------------------------------------------
@
text
@d2 1
a2 1
// $Id: game.C,v 1.30 1995/12/11 21:08:38 daveg Exp $
d100 9
a108 1
    
a204 1
    cerr << first << "\n";
d319 3
a321 1
void game::message(string) {}
d328 4
a331 2
    game_response(int mn, const game *gm, extensions *texts, int playn):
	expired_response(true) {
d351 7
d372 2
d375 1
a375 1
    return new game_response(number_moves(), this, ext, player_num);
@


1.30
log
@it compiles
@
text
@d2 1
a2 1
// $Id: game.C,v 1.29 1995/12/11 20:45:30 jered Exp $
d133 1
a133 1
    p1->state_changed();
d143 1
a143 1
	ref_response(string turi, player *tp1, player *tp2,
d148 2
a149 4
	    uri = turi;
	    p1 = tp1;
	    p2 = tp2;
	}
d152 15
a166 4
	    os << last_component(uri) << string("\n");
	    os << p1->get_name() << string("\n");
	    if (number_moves() == 0)
		os << string("started\n");
d169 1
a169 1
		check(get_move(number_moves(), m),"couldn't get last move");
d172 1
a172 1
	    int time = p1->get_time();
d176 1
a176 1
	    time = p2->get_time();
a179 2
	    extensions *ext;
	    return new normal_response(ext);
d185 1
a185 2
	string uri;
	player *p1, *p2;
d188 1
a188 1
    return new ref_response(my_uri, p1, p2, this, ext);
d194 1
a194 1
    if (!unescape_uri(request, first))
d335 2
a336 1
	g->get_move(g->number_moves(),lastmove);
@


1.29
log
@Display changes.
@
text
@a0 1

d2 1
a2 1
// $Id: game.C,v 1.28 1995/12/11 20:39:25 hartmans Exp $
d83 1
a83 1

d88 4
a91 2
    return game_already_done;
  
d95 5
a99 3
    history.append(m.copy());
    get_player(p)->you_moved(m);
    otherp->opponent_moved(m, p);
d132 53
d191 1
d194 1
a194 1
string player_num_s;
d204 1
a204 1
    if (first == "show"){ 
d207 1
a207 1
	else return get("displayer?player=1",ext);
d214 5
a218 5
				      chess_capture_move m;
				      string s;
				      if (q->find("move", s) && stomove(s,m,get_board()))
					   if ( apply(m,p1_is_def?0:1) == move_invalid)
					       message("Invalid move.");
d226 1
a226 1
    if (first  == "yield" ) {
d231 1
a231 1
    if (first == "detach") {
d237 2
a238 2
    if (first == "attach") {
				// We pass it off  to p1 then p2; if neither succeeds then we return an error.
d330 2
a331 1
	os << "Last move: " << lastmove->display();
d343 1
a343 1
      const game *g;
d347 2
a348 2
  };
  return new game_response(number_moves(), this, ext, player_num);
@


1.28
log
@fix forfeit
@
text
@d3 1
a3 1
// $Id: game.C,v 1.26 1995/12/11 13:26:32 hartmans Exp $
d265 2
d271 4
@


1.27
log
@More display modifications.
@
text
@d1 1
d4 1
d138 1
a138 1
	if (q->find("player", player_num_s)) {
@


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

* Fix can_go in player

* Fix set time.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.25 1995/12/11 08:50:33 rgmisra Exp $
d267 1
a270 1
      g->get_board()->display(exts, os, pnum);
d272 1
@


1.25
log
@add a "Back to top" link
@
text
@d2 1
a2 1
// $Id: game.C,v 1.24 1995/12/11 07:09:33 hartmans Exp $
d162 1
a162 1
    else if (request == "opponent_move") {
@


1.24
log
@In game, several compatability protocol fixes.
Also, update to deal with struct open i  templates.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.23 1995/12/10 09:55:13 hartmans Exp $
d271 1
@


1.23
log
@Web fixes
@
text
@d2 1
a2 1
// $Id: game.C,v 1.22 1995/12/10 05:14:26 hartmans Exp $
d305 1
@


1.22
log
@Fix compilation problems,
Add several methods to deal with backward
compatibility protocol.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.21 1995/12/08 04:20:52 hartmans Exp $
d15 1
a15 1

d167 19
d250 1
a250 1
  class game_response: public normal_response {
d255 1
a255 1
    normal_response(true) {
@


1.21
log
@Insert clock debugging code.
Fix resync URI.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.20 1995/12/07 23:18:46 hartmans Exp $
d13 2
d145 23
d283 1
a283 1
  sprintf(buf, "%lu", number_moves());
@


1.20
log
@Implement uri_with_move()
@
text
@d2 1
a2 1
// $Id: game.C,v 1.19 1995/12/06 14:11:26 daveg Exp $
d171 2
a172 1
		    os<<g->uri()<<g->number_moves()<<"/"<<rest_components(request)<<
@


1.19
log
@fixed bug in apply
@
text
@d2 1
a2 1
// $Id: game.C,v 1.18 1995/12/04 06:28:34 hartmans Exp $
d4 1
d253 7
@


1.18
log
@Fix const error so game compiles again
@
text
@d2 1
a2 1
// $Id: game.C,v 1.17 1995/12/04 06:04:19 jered Exp $
d100 1
a100 1
  if ((pwinning = b->winner()) != 0)
d108 1
a108 1
    }
@


1.17
log
@Prelim. impl. of game::display.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.16 1995/12/04 05:00:10 jered Exp $
d208 1
a208 1
    game_response(int mn, game *gm, extensions *texts, int playn):
d229 1
a229 1
    game *g;
@


1.16
log
@Added chess_display.C; implemented chess_display_board::display
@
text
@d2 1
a2 1
// $Id: game.C,v 1.15 1995/12/03 19:57:01 hartmans Exp $
d203 32
a234 2
http_response *game::display(extensions* , int) const {
    return new error_response(http_response::NOT_IMPLEMENTED, "OK, OK, so it's kind of useless, but still, it's strue.");
@


1.15
log
@Fix timing in player,
add get to human_player,
fix error in game::apply
@
text
@d2 1
a2 1
// $Id: game.C,v 1.14 1995/12/03 01:17:49 hartmans Exp $
d20 1
a20 1
image_uri = image_uri_in;
d24 1
a24 1
p1->associate(this);
@


1.14
log
@Implement image_base and associated
constructor change.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.13 1995/12/02 06:00:31 hartmans Exp $
d82 1
a82 1
  player *otherp = (p == 0)?p1:p2;
@


1.13
log
@Add game::get
@
text
@d2 1
a2 1
// $Id: game.C,v 1.12 1995/12/01 04:50:14 hartmans Exp $
d14 2
a15 1
	    bool p1_is_def_in):history(50) {
d20 1
d221 1
@


1.12
log
@Associate with players in game
@
text
@d2 1
a2 1
// $Id: game.C,v 1.11 1995/12/01 03:39:03 hartmans Exp $
d11 1
d123 75
a197 3
http_response *game::get(string, extensions *ext) {
    return display(ext, 0);
};
d213 6
@


1.11
log
@Integrate oral presentation changes into main line.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.10.2.2 1995/11/30 09:44:53 hartmans Exp $
d21 2
@


1.10
log
@Fix bugs so it builds
@
text
@d2 1
a2 1
// $Id: game.C,v 1.9 1995/11/30 04:26:48 hartmans Exp $
d10 1
d119 19
@


1.10.2.1
log
@Fix game bugs; implement
stubs
@
text
@d2 1
a2 1
// $Id: game.C,v 1.10 1995/11/30 06:31:51 hartmans Exp $
a9 1
#include <ps5/error_response.h>
a117 11

http_response *game::get(string, extensions *ext) {
    return display(ext, 0);
};

void game::message(string) {}

http_response *game::display(extensions* , int) const {
    return new error_response(http_response::NOT_IMPLEMENTED, "OK, OK, so it's kind of useless, but still, it's strue.");
}

@


1.10.2.2
log
@change stuff
@
text
@d2 1
a2 1
// $Id: game.C,v 1.10.2.1 1995/11/30 08:33:52 hartmans Exp $
a129 8

int game::player_index(const player *p ) const {
    if (p == p1 )
	return 0;
    else if (p == p2)
	return 1;
    else return -1;
}
@


1.9
log
@player:  Deal with clock stuff
game: fix argument bogosity
@
text
@d2 1
a2 1
// $Id: game.C,v 1.8 1995/11/28 03:31:33 hartmans Exp $
d17 1
a17 1
  p1_is_def = p1_is_first_in;
@


1.8
log
@Change players to be indexes, add a few new methods.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.7 1995/11/22 07:37:13 daveg Exp $
d12 1
a12 1
	    bool p1_is_first_in):history(50) {
d17 1
a17 1
  p1_is_first = p1_is_first_in;
@


1.7
log
@bug fixes in apply
@
text
@d2 1
a2 1
// $Id: game.C,v 1.6 1995/11/21 06:54:12 hartmans Exp $
d74 3
a76 3
game::move_result game::apply (move &m, player *p) {
  check ((p == p1)||(p == p2), "only my players can submit moves.");
  player *otherp = (p == p1)?p1:p2;
d84 1
a84 1
    p->you_moved(m);
d92 1
a92 1
  player *pwinning;
d95 1
a95 1
    win = (pwinning == p1);
d100 8
a107 10
player * game::winner() const {
    if (win == -1)
	return 0;
    else return get_player(win);
}

void game::forfeit (player *p) {
  check ((p == p1)||(p == p2), "player forfeits but not actually a player");
  check ((win == -1) || (get_player(win) != p), "Winner wants to forfeit.");
  if (p == p1)
@


1.6
log
@Changes for Jered to build
@
text
@d2 1
a2 1
// $Id: game.C,v 1.5 1995/11/21 06:08:53 jered Exp $
d77 1
a77 1
  if (win)
d94 2
a95 2
  if ((pwinning = b->winner()) == 0)
    win = (pwinning == p1)?p1:p2    ;
@


1.5
log
@Added test_board.C, and Changelog, Updated TODO.
Modified game.C.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.4 1995/11/21 05:22:46 hartmans Exp $
d101 3
a103 3
  if (win == -1)
    return -1;
  else return get_player(win);
@


1.4
log
@Lots of fixes to make stuff compile
@
text
@d2 1
a2 1
// $Id: game.C,v 1.3 1995/11/20 07:58:56 hartmans Exp $
d11 10
a20 11
game::game (board *b_in, player *p1_in, player *p2_in, string uri_in, bool p1_is_first_in):
history(50)
{
    p1 = p1_in;
    p2 = p2_in;
    b = b_in;
    my_uri = uri_in;
    p1_is_first = p1_is_first_in;
win = -1;
    b->associate(this);
    state_changed();
a22 1

d24 6
a29 6
    delete p1;
    p1 = 0;
    delete p2;
    p2 = 0;
    delete b;
    b = 0;
d51 2
a52 2
    index = 0;
    a = history;
d54 1
d56 5
a60 5
    if ( index == a->length())
	return false;
    
    m = a->fetch(index++);
    return true;
d64 1
a64 1
    return new history_gen(&history);
d66 1
a66 1
;
d68 4
a71 4
    if ( (number < 0) || (number >= history.length()))
	 return false;
	 m = history[number];
	 return true;
a73 2


d75 11
a85 4
    check ((p == p1)||(p == p2), "only my players can submit moves.");
    player *otherp = (p == p1)?p1:p2;
    if (win)
	return game_already_done;
d87 2
a88 13
    move_result res = b->apply(m, p);
    switch (res) {
    case ok:
	history.append(m.copy());
	p->you_moved(m);
	otherp->opponent_moved(m, p);

    default:;
// Do nothing, I guess	
	
	// Do something if necessary
    }
player *pwinning;
d90 5
a94 1
if ((pwinning = b->winner()) == 0)
d96 2
a97 2
return res;
    
a99 1

d101 3
a103 3
    if (win == -1)
	return -1;
    else return get_player(win);
d107 5
a111 5
    check ((p == p1)||(p == p2), "player forfeits but not actually a player");
    check ((win == -1) || (get_player(win) != p), "Winner wants to forfeit.");
    if (p == p1)
	win = 1;
    else win = 0;
d115 2
a116 2
    p1->state_changed();
    p2->state_changed();
@


1.3
log
@Implemented calls to you_move and opponent_moved.
@
text
@d2 2
a3 1
// $Id: game.C,v 1.2 1995/11/20 06:21:02 hartmans Exp $
d21 1
d35 1
d37 1
a37 1
    history_gen(array <move *> *history);
d64 2
a65 2
generator <move *> game::move_history() const {
    return new history_gen(history);
d80 2
d89 3
a91 3
	// Check if someone won.
    default:
// Also check if someone won.
d95 4
d112 1
a112 1
    checks ((win == -1) || (get_player(win) != p), "Winner wants to forfeit.");
d118 1
a118 1
void game::state:changed() {
d121 3
@


1.2
log
@Implement forfeit and winner


1) change state method
2) implications for move ordering, etc.
@
text
@d2 1
a2 1
// $Id: game.C,v 1.1 1995/11/20 00:52:39 hartmans Exp $
d76 2
d82 3
a84 1
	// Notify players that the move was accepted.
d86 2
d109 3
@


1.1
log
@Support and changes for game
@
text
@d2 1
a2 1
// $Id$
d18 1
d86 15
@
