[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pbmserv-dev] quoridor 4 player?



I have attached a patch to make make quoridor work for 4 players.

I have _not_ changed PrintBoardAs.  I'm hoping dzander or whoever wrote it
will do that, since it would take me as long for that one function as it
took me to fix the logic in the other places.  Hint: I don't think 90
degree rotations would be a good idea, since it would change the meaning
of '-' and '/'.

~ John Williams


On Sat, 14 Sep 2002, Douglas Zander wrote:

> I looked at the code and let me tell you, it will be *very* hard
> to change it as it is.  Sorry, but I don't think I'll be messing
> with it.  I would like to have functions that are general purpose
> but unfortunately, the quoridor program was written for one purpose
> and one purpose only, to play two-player only.  I believe a total
> overhaul of the program would be required to make it an optional
> 2 or 4 player game.
>
>
> On Sat, 14 Sep 2002, Richard Rognlie wrote:
>
> > I should just be a matter of making the Init() function aware of 2 or 4...
> > and the start position... and changing the number of fences per
> > player from 10 to 5 (I think)
> >
> > But I've not looked at the code at all yet...
> >
> > On Sat, Sep 14, 2002 at 05:10:10PM -0400, Benjamin Good wrote:
> > >
> > >
> > > from reading the help file, it looks like the server is only programmed for
> > > 2-player quoridor.  is that correct?  it's been years since i played it, but
> > > i seem to remember that 4-player quoridor was a lot of fun.  how difficult
> > > would it be to add that in?
> > >
> > > thanks,
> > > ben
> > > asdf
> > >
> > > _________________________________________________________________
> > > Chat with friends online, try MSN Messenger: http://messenger.msn.com
> > >
> > >
> > > To unsubscribe, send a message to esquire@gamerz.net with
> > > 	unsubscribe pbmserv-dev@gamerz.net
> > > as the BODY of the message.  The SUBJECT is ignored.
> > >
> >
> > --
> >  /  \__  | Richard Rognlie / Sendmail Ninja / Gamerz.NET Lackey
> >  \__/  \ | http://www.gamerz.net/rrognlie/    <rrognlie@gamerz.net>
> >  /  \__/ | No trees were killed in the sending of this message.
> >  \__/    | However, a great many instructions were executed.
> >
> >
> > To unsubscribe, send a message to esquire@gamerz.net with
> > 	unsubscribe pbmserv-dev@gamerz.net
> > as the BODY of the message.  The SUBJECT is ignored.
> >
>
>
>
> --
>  Douglas Zander
>  Did you know about the Plakoto and Moultezim Tournaments I will be
>  running at Richard's PBeM Server?  There will be prizes!  Sign up now:
>  www.gamerz.net  and contact me, userid: dzander   for details
>
>
>
>
> To unsubscribe, send a message to esquire@gamerz.net with
> 	unsubscribe pbmserv-dev@gamerz.net
> as the BODY of the message.  The SUBJECT is ignored.
>
--- quoridor.h	2002/09/17 03:32:05	1.1
+++ quoridor.h	2002/09/17 03:32:12
@@ -20,9 +20,9 @@
 	virtual void PrintBoardAs(FILE *fp, int what, int which);
 	
 	virtual char Blank(void) { return BLANK; }	
-	virtual const char *PlayerNames(int n) { return "Player 1\0Player 2"+n*9; }
+	virtual const char *PlayerNames(int n) { return "Player 1\0Player 2\0Player 3\0Player 4"+n*9; }
 
-	virtual const char PlayerPieces(int n) { return "OX"[n]; }
+	virtual const char PlayerPieces(int n) { return "OXHS"[n]; }
 // what character is used to represent a vertical fence in data file?
 	virtual const char VFence(void) { return '|'; }
 // what character is used to represent a vertical fence in move string?
@@ -31,7 +31,7 @@
 	virtual const char HFMove(void) { return '-'; }
 	virtual const char GridPoints(void) { return '+'; }
 
-    virtual const int MaxPlayers(void) { return 2; }
+    virtual const int MaxPlayers(void) { return 4; }
     
    	virtual const char *MakeMove(const char *move);
 	virtual const char *ForcedMove(void);
@@ -40,6 +40,7 @@
     
     virtual int IsOpponentTrapped(void);
     virtual void Cleanup(int ci, int cj);
+    virtual char* playerside(void);
 
 // Non-board specific
 	virtual const char *GameType(void) { return "Quoridor"; }
--- quoridor.cpp	2002/09/17 03:32:05	1.1
+++ quoridor.cpp	2002/09/17 03:32:12
@@ -342,48 +342,86 @@
 
 int Quoridor::IsOpponentTrapped(void)
 {
-int i,j;
-int ci,cj;
-int grow;
-   
-   if (1-CurrentPlayer() == 0) grow = MinRow(); else grow = MaxRow();   
-   
-   //remove CurrentPlayer
-   for (i = MinRow(); i <= MaxRow(); i+=2)
-      for (j = MinCol(); j <= MaxCol(); j+=2)
-         if (GetAt(i,j)==PlayerPieces(CurrentPlayer())) {
-            ci = i; cj = j;
-            PutAt(i,j,Blank());
-         }
-
-   
-   for (i = MinCol(); i <= MaxCol(); i+=2) PutAt(grow,i,'1');
-      
-   
-for (int k = 0; k <= 80; k++)   
-   for (i = MinRow(); i <= MaxRow(); i+=2)
-      for (j = MinCol(); j <= MaxCol(); j+=2)
-         if (GetAt(i,j)=='1') {
-            if (!(GetAt(i-1,j) == '-'))
-               if (GetAt(i-2,j)==PlayerPieces(1-CurrentPlayer()))
-                  { Cleanup(ci,cj); return 0;}
-               else PutAt(i-2,j,'1');
-            if (!(GetAt(i+1,j) == '-'))
-               if (GetAt(i+2,j)==PlayerPieces(1-CurrentPlayer()))
-                  { Cleanup(ci,cj); return 0;}       
-               else PutAt(i+2,j,'1');
-            if (!(GetAt(i,j-1) == '|')) 
-               if (GetAt(i,j-2)==PlayerPieces(1-CurrentPlayer()))
-                  { Cleanup(ci,cj); return 0;}         
-               else PutAt(i,j-2,'1');            
-            if (!(GetAt(i,j+1) == '|')) 
-               if (GetAt(i,j+2)==PlayerPieces(1-CurrentPlayer()))
-                  { Cleanup(ci,cj); return 0;}   
-               else PutAt(i,j+2,'1');
-         }
-               
-   Cleanup(ci, cj);
-   return 1;
+	int i,j;
+	int pr[4],pc[4];
+	char pi;
+	int n;
+	int found;
+	
+	// store player positions
+	for (i = MinRow(); i <= MaxRow(); i+=2) {
+		for (j = MinCol(); j <= MaxCol(); j+=2) {
+			pi = GetAt(i,j);
+			if (pi != Blank()) {
+				int pp = -1;
+				for(int ii=0; ii<players.Count(); ii++) {
+					if (pi==PlayerPieces(ii)) pp = ii;
+				}
+				if (pp>=0) {
+					pr[pp] = i;
+					pc[pp] = j;
+				}
+			}
+		}
+	}
+
+	for (int ii=0 ; ii<players.Count(); ii++ ) {
+		if (ii == CurrentPlayer()) continue;
+
+		Cleanup(pr[ii],pc[ii]);
+
+		char *side = playerside();
+		switch (side[ii]) {
+		case 'N':
+			for (i=MinCol(); i<=MaxCol(); i+=2) PutAt(MinRow(),i,'1');
+			break;
+		case 'E':
+			for (i=MinRow(); i<=MaxRow(); i+=2) PutAt(i,MinCol(),'1');
+			break;
+		case 'S':
+			for (i=MinCol(); i<=MaxCol(); i+=2) PutAt(MaxRow(),i,'1');
+			break;
+		case 'W':
+			for (i=MinRow(); i<=MaxRow(); i+=2) PutAt(i,MaxCol(),'1');
+			break;
+		}	
+
+		// flood fill	
+		found = 0;
+		do {
+			n=0;
+			for (i = MinRow(); i <= MaxRow(); i+=2)
+				for (j = MinCol(); j <= MaxCol(); j+=2)
+					if (GetAt(i,j)=='1') {
+						if (i>MinRow() && !(GetAt(i-1,j) == '-')) {
+							if (GetAt(i-2,j)>='A') found=1;
+							if (IsBlank(i-2,j)) { n++; PutAt(i-2,j,'1'); }
+						}
+						if (i<MaxRow() && !(GetAt(i+1,j) == '-')) {
+							if (GetAt(i+2,j)>='A') found=1;
+							if (IsBlank(i+2,j)) { n++; PutAt(i+2,j,'1'); }
+						}
+						if (j>MinCol() && !(GetAt(i,j-1) == '|')) {
+							if (GetAt(i,j-2)>='A') found=1;
+							if (IsBlank(i,j-2)) { n++; PutAt(i,j-2,'1'); }
+						}
+						if (j<MaxCol() && !(GetAt(i,j+1) == '|')) {
+							if (GetAt(i,j+2)>='A') found=1;
+							if (IsBlank(i,j+2)) { n++; PutAt(i,j+2,'1'); }
+						}
+					}
+
+		} while (!found && n);
+
+		// blocked if !found
+		if (!found) break;
+	}
+					
+	Cleanup(pr[0],pc[0]);
+	for (int ii=0; ii<players.Count(); ii++) {
+		PutAt(pr[ii],pc[ii],PlayerPieces(ii));
+	}
+	return !found;
 }
 
 void Quoridor::Cleanup(int ci, int cj)
@@ -391,20 +429,46 @@
 int i,j;
    for (i = MinRow(); i <= MaxRow(); i+=2)
       for (j = MinCol(); j <= MaxCol(); j+=2)
-         if (GetAt(i,j)=='1') PutAt(i,j,Blank());
+         /*if (GetAt(i,j)=='1')*/ PutAt(i,j,Blank());
    PutAt(ci,cj,PlayerPieces(CurrentPlayer()));
 }
 
 int Quoridor::IsGameOver(const char *&winner)
 {
-int j;
-   for (j = MinCol(); j <= MaxCol(); j++) {
-      if (GetAt(MinRow(),j) == 'O') 
-         { winner = players[0]; return 1; }
-      if (GetAt(MaxRow(),j) == 'X') 
-         { winner = players[1]; return 1; }
-   }
-   return 0;
+	//int j;
+	char *side = playerside();
+
+	for(int i=0; i<players.Count() ; i++ ) {
+		switch (side[i]) {
+		case 'N':
+			for (i=MinCol(); i<=MaxCol(); i+=2)
+				if (GetAt(MaxRow(),i) == PlayerPieces(i))
+					{ winner = players[i]; return 1; }
+			break;
+		case 'E':
+			for (i=MinRow(); i<=MaxRow(); i+=2)
+				if (GetAt(i,MinCol()) == PlayerPieces(i))
+					{ winner = players[i]; return 1; }
+			break;
+		case 'S':
+			for (i=MinCol(); i<=MaxCol(); i+=2)
+				if (GetAt(MinRow(),i) == PlayerPieces(i))
+					{ winner = players[i]; return 1; }
+			break;
+		case 'W':
+			for (i=MinRow(); i<=MaxRow(); i+=2)
+				if (GetAt(i,MaxCol()) == PlayerPieces(i))
+					{ winner = players[i]; return 1; }
+			break;
+		}
+	}
+	//for (j = MinCol(); j <= MaxCol(); j++) {
+	//	if (GetAt(MinRow(),j) == 'O') 
+	//		{ winner = players[0]; return 1; }
+	//	if (GetAt(MaxRow(),j) == 'X') 
+	//		{ winner = players[1]; return 1; }
+	//}
+	return 0;
 }
 
 const char *Quoridor::ForcedMove(void)
@@ -412,27 +476,48 @@
    return 0;
 }
 
+char *Quoridor::playerside(void)
+{
+	if (players.Count() == 4)
+		return "NESW";
+	else
+		return "NS";
+}
 
 int Quoridor::Init(void)
 {
-   int rowlen, collen;
+	int rowlen, collen;
 
-   if (parameters.Count() > 0)
-      return Error("%s does not take parameters", GameType());
+	if (parameters.Count() > 0)
+		return Error("%s does not take parameters", GameType());
+	if (players.Count() == 3)
+		return Error("%s cannot be played with 3 players.", GameType());
  
-   Board2D::Init(strlen(Rows),strlen(Cols));
+	Board2D::Init(strlen(Rows),strlen(Cols));
 
-   PutAt(strlen(Rows)-1, 8, PlayerPieces(0));
-   PutAt(0, 8, PlayerPieces(1));
-   
-   fences.Init().Add(10).Add(10);
-
-   rowlen=strlen(Rows)-1; collen=strlen(Cols)-1;
-   for (int xx=1; xx<rowlen; xx+=2)
-     for (int yy=1; yy<collen; yy+=2)
+	char *side = playerside();
+	for (int i=0 ; i<players.Count() ; i++ ) {
+		switch (side[i]) {
+		case 'N': PutAt(MaxRow(),MaxCol()/2,PlayerPieces(i)); break;
+		case 'E': PutAt(MaxRow()/2,MaxCol(),PlayerPieces(i)); break;
+		case 'S': PutAt(MinRow(),MaxCol()/2,PlayerPieces(i)); break;
+		case 'W': PutAt(MaxRow()/2,MinCol(),PlayerPieces(i)); break;
+		}
+	}
+	//PutAt(strlen(Rows)-1, 8, PlayerPieces(0));
+	//PutAt(0, 8, PlayerPieces(1));
+	
+	fences.Init();
+	for (int i=0; i<players.Count() ; i++ ) {
+		fences.Add(20/players.Count());
+	}
+
+	rowlen=strlen(Rows)-1; collen=strlen(Cols)-1;
+	for (int xx=1; xx<rowlen; xx+=2)
+		for (int yy=1; yy<collen; yy+=2)
 	board[xx][yy] = GridPoints();
 
-   return 1;
+	return 1;
 }
 
 int Quoridor::ReadBoard(GameFile &game)