/* 
  Copyright 1991 Mario Goertzel and Matthew Sorrels
 
  Permission to use, copy, modify, distribute, and sell this software and its
  documentation for any purpose is hereby granted without fee, provided that
  the above copyright notice appear in all copies and that both that
  copyright notice and this permission notice appear in supporting
  documentation, and that the name of the author not be used in advertising or
  publicity pertaining to distribution of the software without specific,
  written prior permission.  The authors make no representations about the
  suitability of this software for any purpose.  It is provided "as is"
  without express or implied warranty.
 
  MARIO GOERTZEL AND MATTHEW SORRELS DISCLAIMS ALL WARRANTIES WITH 
  REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 
  MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MATTHEW SORRELS BE 
  LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
  Authors:  Mario Goertzel and Matthew Sorrels
*/
/*
 * Capture The Flag
 *
 * Mario Goertzel <mg2p+@andrew.cmu.edu>
 * Matthew Sorrels <ms90+@andrew.cmu.edu>
 *
 * May 11, 1991
 */
#include <stdio.h>
#include <strings.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include "capture.h"
#include "CaptureIcon.xbm"

extern struct Board mainBoard;
extern struct Piece pieces1[15];
extern struct Piece pieces2[15];
extern char *pieceNames[];

#define PIECES 40
extern int pieceCount[];

extern int finalwinner;
extern int turnnum;
extern int turn;
extern int setup1;
extern int setup2;

extern char *StatusText[2];
extern char *Player1Text;
extern char *Player2Text;
extern int TextSize[2];

extern Display *Display1, *Display2;
extern int Screen1, Screen2;
extern int Depth1, Depth2;
extern Colormap Colormap1, Colormap2;
extern unsigned long BackColor1, BackColor2;
extern unsigned long ForeColor1, ForeColor2;
extern unsigned long PieceColor1, PieceColor2;
extern unsigned long OppColor1, OppColor2;

extern Window wind1, wind2;
extern Window board1, board2;
extern Window status1, status2;
extern Window talk1, talk2;
extern Window otherTalk1, otherTalk2;
extern GC draw1, draw2, erase1, erase2, xor1, xor2, invert1, invert2;  
extern XFontStruct *font1, *font2;
extern Cursor cursor1, cursor2;
extern char *BaseDir;
extern char *FontName;
extern int textwidth1, textwidth2;
extern int textheight1, textheight2;
extern int BorderWidth;

extern int Isinvert1, Isinvert2;
extern int InvertI1, InvertJ1;
extern int InvertI2, InvertJ2;

#define ABS(i) ((i < 0) ? -(i) : (i))

int ValidateMove(player, i1, j1, i2, j2)
int i1, j1, i2, j2;
{
  int v1 = mainBoard.location[i1][j1].value;
  int oplayer = (player == 1) ? 2 : 1;

  if (mainBoard.location[i1][j1].status != player) return INVALID;

  if (turn != player) return 0;

  /* NoMoves calls with invalid arguments */
  if ((i1 < 0) || (i2 < 0) || (j1 < 0) || (j2 < 0)) return INVALID;
  if ((i1 > 9) || (i2 > 9) || (j1 > 9) || (j2 > 9)) return INVALID;

  if ((i1 != i2) && (j1 != j2)) return INVALID;

  if ((v1 == FLAG) || (v1 == BOMB)) return INVALID;
  
  if (mainBoard.location[i2][j2].status == OPEN) {
    /* MOVE */
    if (v1 == SCOUT) {
      int t, dir;
      if (i1 != i2) {
	dir = (i1 < i2) ? 1 : -1;
	for(t = i1+dir; t != i2; t+=dir) {
	  if (mainBoard.location[t][j2].status != OPEN) return INVALID;
	}
      } else {
	dir = (j1 < j2) ? 1 : -1;
	for(t = j1+dir; t != j2; t+=dir) {
	  if (mainBoard.location[i2][t].status != OPEN) return INVALID;
	}
      }
    } else if ((ABS(i1 - i2) > 1) || ABS(j1 - j2) > 1) return INVALID;

    return VALID;
  }
  if (mainBoard.location[i2][j2].status == oplayer) {
    /* STRIKE */
    if ((ABS(i1 - i2) > 1) || ABS(j1 - j2) > 1) return INVALID;
    return STRIKE;
  }
  return INVALID;
}

/*
 *  i1,j1 is attacking i2,j2
 * 
 * 0 - 1 wins
 * 1 - 2 wins
 * 2 - tie
 * 3 - bomb defending
 *
 */
int Winner(i1, j1, i2, j2)
int i1, j1, i2, j2;
{
  int win = 1;
  int v1 = mainBoard.location[i1][j1].value;
  int v2 = mainBoard.location[i2][j2].value;

  if (v1 == v2) return 2; /* tie */

  if (v1 < v2) win = 0; /* assume lesser value wins */

  if ((v1 == SPY) && (v2 == MARSHAL)) win = 0; /* spy wins if it attacks a marshall */

  if (v2 == BOMB) win = 3; /* assume a defending bomb wins */

  if ((v1 == MINER) && (v2 == BOMB)) win = 0; /* miner takes out bomb */

  if (v2 == FLAG) finalwinner = mainBoard.location[i1][j1].status;

  return win;
}

/*
 * 0 - 1 or more moves left for player
 * 1 - no moves for left player
 */
int NoMoves(player)
int player;
{
  int i, j;

  for(i = 0; i < 10; i++)
    for(j = 0; j < 10; j++) {
      if (ValidateMove(player, i, j, i-1, j) != INVALID) return 0;
      if (ValidateMove(player, i, j, i, j-1) != INVALID) return 0;
      if (ValidateMove(player, i, j, i+1, j) != INVALID) return 0;
      if (ValidateMove(player, i, j, i, j+1) != INVALID) return 0;
    }
  return 1;
}
