'===========================================================================
' Subject: INTELLIGENT OTHELLO                Date: 12-10-97 (23:59)       
'  Author: Antoni Gual                        Code: QB, PDS                
'  Origin: agual@eic.ictnet.es              Packet: GAMES.ABC
'===========================================================================
'--------------------------------------------------------------------------
'OTHELLO.BAS
'More or less inteligent othello player for Quick Basic (not QBasic)
'By Antoni Gual     agual@eic.ictnet.es
' 
'I spent all my time with the evaluating routine, so forgive my graphics
'It Will not work without a mouse
'Any suggestions about evaluating routine or user interface will be welcome
'Any suggestions about graphics will be politely answered. (I hate doing
'computer graphics)
'Just click with the mouse the place whwre you want to move
'As i have a 486 i never used the program at a level higher than 5, so i can't
'guarantee the higher levels.
'Enjoy it!
'----------------------------------------------------------------------------

DECLARE FUNCTION MouseInt% (func%, fil%, col%)
DECLARE SUB PointCount (niv%, clr%, ptosyo%, ptoscont%)
DECLARE SUB DebugRank (niv%, a() AS ANY, curs%)
DECLARE SUB EvaluatePos (niv%, punt%, clr%)
DECLARE SUB PCThinks (posi%, punt%, niv%, clr%)
DECLARE SUB DisplayMove (clr%, niv%)
DECLARE SUB UserInput (a$, x%, y%)
DECLARE SUB HumanMoves (posicion%)
DECLARE SUB NextMove (clr%, punt%)
DECLARE SUB DisplMessage (clr%, txt$, pulse%)
DECLARE SUB Presentacion ()
DECLARE SUB FichaVer (posc%, niv%)
DECLARE SUB AskUser (in%, min%, max%, lloc%, txt$)
DECLARE SUB CopyGame (de%, a%)
DECLARE SUB LegalMove (posicion%, puntos%, LEV%, clr%, opcion%)
DECLARE SUB SrchForValidMove (LEV%, clr%, posi%)
DECLARE SUB InitDisplay ()

DEFINT A-Z
TYPE elrank                         ' ranking jugadas en PCThinks
	posi AS INTEGER
	punt AS INTEGER
END TYPE

TYPE RegTypeX                          'for mouse interrupt.
	  ax    AS INTEGER
	  bx    AS INTEGER
	  cx    AS INTEGER
	  dx    AS INTEGER
	  bp    AS INTEGER
	  si    AS INTEGER
	  di    AS INTEGER
	  flags AS INTEGER
	  ds    AS INTEGER
	  es    AS INTEGER
END TYPE
DECLARE SUB INTERRUPTX (intnum AS INTEGER, inreg AS RegTypeX, outreg AS RegTypeX)


CONST true = -1, false = NOT true
												
CONST numrank = 5                   ' n§ jugadas que considera PCThinks
CONST hjEsLegal = 1, hjJuega = 3    ' opciones LegalMove
CONST maxnivel = 10                 ' Profundidad maxima  PCThinks

'Valores validos en el array Game
CONST Humano = -1, PeCe = 1         ' Fichas de los jugadores. PC=PeCe, Humano=Humano
CONST muro = 9, libre = 0           ' Limites tablero y casilla vac¡a
'constantes para dibujo tablero y fichas
CONST anchorej = 32
CONST dsplvert = 24
CONST dsplhori = 28

'constantes raton
CONST minit = 0, mshow = 1, mhide = 2, mget = 3, mset = 4, mpres = 5
CONST mrele = 6, mxlim = 7, mylim = 8, mattr = 10
CONST mbleft = 1, mbright = 2, mbcenter = 4


'main Array---------------------------------------------------------
DIM SHARED Game(0 TO 99, -2 TO maxnivel)  AS INTEGER
								 ' levels    
								 ' 0          : real game
								 ' 1 a maxniv,: levels of evaluation
								 '-1          : pieces captured, blinking
								 '-2          : position before last human move

					  'A game is a 1dimensional array, by rows
					  'Game(12,x) = Piece at 1st row, 2nd column
					  'j(0,x),(X0,x),(9X,x),(X9,x) limits of playground
'--------------------------------------------------------------------------
'This comes straigth from a game for the ZX-Spectrum, it used this curious           
'representation to speed up the calculation of the correctness of the moves,
'the captures and the posibility of a move.It was supposed to be faster
'to work with an one dimensional array than with a two dimension, i suppose
'the diffference in a PC is not so big. However, as i added levels to
'evaluate moves, replays,etc, Game() became two dimensional again.
'
'I can't credit anyone for the idea, it was from a game in a magazine
'i lost many years ago. The game also played by itself, but
'only putted his pieces in the first legal place it found, so it was too
'easy to win. There started all..Aah, the old times....
'-------------------------------------------------------------------------


DIM SHARED Score(Humano TO PeCe) AS INTEGER     ' puntuacion

DIM SHARED PlayLevel AS INTEGER                    ' PlayLevel juego elegido
DIM SHARED anterior AS INTEGER, HayMouse AS INTEGER

'Array that preserves the 8 directions the moves can be tested
'In the strange representation of Game() you can follow a line in the
'playground by adding a constant to the current position
' +/- 1 is rowwise  +/-10 is columnwise and +/-9, and +/-11 are the two
'diagonals

DIM SHARED direcc(7) AS INTEGER        '
FOR i = 0 TO 7: READ direcc(i): NEXT'  'inicializa direcciones
DATA 1,-1,10,-10,11,-11,9,-9



	
PlayLevel = 1

IF MouseInt(minit, 0, 0) THEN
		  HayMouse = true
ELSE
		  PRINT "No mouse, No game"
		  END
END IF

'main loop---------------------------------------------------------------
DO
	Presentacion
	AskUser PlayLevel, 1, maxnivel, 25, "Evaluation Level"
							 ' dibuja InitDisplay
	ERASE Game
	FOR i = 0 TO 9
		Game(i, 0) = muro
		Game(90 + i, 0) = muro
		Game(10 * i, 0) = muro
		Game(10 * i + 9, 0) = muro
	NEXT
 
	'Do the 4 initial moves
	Game(44, 0) = Humano
	Game(55, 0) = Humano
	Game(45, 0) = PeCe
	Game(54, 0) = PeCe
	CopyGame 0, -2
	anterior = 1
	InitDisplay
	DisplayMove 0, 0                           ' display
  
	tablas = 0: Player = PeCe
  
													' bucle jugadas
	DO
		NextMove Player, pt
	  
		IF pt = 0 THEN
			tablas = tablas + 1
		ELSE
			tablas = 0
		END IF
	  
		IF pt > 0 THEN DisplayMove Player, 0
		
	  
		Player = -Player

	LOOP UNTIL Score(Player) + Score(-Player) = 64 OR tablas = 2 OR Score(Player) * Score(-Player) = 0
  
	' final  partida
	
	SELECT CASE Score(Humano)
	CASE IS < Score(PeCe)
		DisplMessage PeCe, "You Won!", 1
	CASE IS > Score(PeCe)
	 
		DisplMessage Humano, "You Lost!", 1
	CASE IS = Score(PeCe)
		 DisplMessage Humano, "Equals!", 1
	END SELECT
  
	COLOR 7: LOCATE 28, 1: INPUT "Another Game? [Y]/N "; a$
LOOP UNTIL UCASE$(a$) = "N"

END

SUB AskUser (in, min, max, lloc, txt$)
	'Displays a string, waits for numeric user entry, looks if the entry is
	'between limits max and min .If not, re-asks, if yes, erases all and returns
	'with value in in
  
	IF lloc < 0 THEN CLS
	lloc = ABS(lloc)
	DO
		IF lloc > 0 THEN LOCATE lloc, 1
		txt1$ = txt$ + ":" + STR$(min) + "<" + STR$(max) + " (" + STR$(in) + ") "
		PRINT txt1$; SPACE$(60 - LEN(txt1$)); ":"; : INPUT Entrada$
		IF Entrada$ = "" THEN EXIT DO
		IF VAL(Entrada$) <> 0 THEN
			in = VAL(Entrada$)
		ELSEIF Entrada$ = "0" THEN
			in = VAL(Entrada$)
		END IF
	LOOP UNTIL in >= min AND in <= max
END SUB

SUB CopyGame (de, a)
	'copies the game from one level of the array Game() to another

	FOR i = 0 TO 99: Game(i, a) = Game(i, de): NEXT
END SUB

SUB DebugRank (Level, a() AS elrank, curs)
	'only debugging. Displays renking of best moves being calculated by PC

	vertpos = (Level - 1) * 10 + 1
	IF curs > 0 THEN
		LOCATE 21, Level * 10 + 1: PRINT curs
	END IF
		IF Level MOD 2 THEN COLOR 12 ELSE COLOR 11
		
		FOR i = 1 TO numrank
			LOCATE 21 + i, vertpos: PRINT USING "###### ##"; a(i).punt; a(i).posi
		NEXT
		'nb$ = INPUT$(1)
	

END SUB

SUB DisplayMove (Player, Level)
	'Displays new move, blinking the pieces captured and the score
  
	IF Player <> 0 THEN
		a = 7: B = Player
		FOR i = 1 TO 10                              'Blink
			tim1! = TIMER
			FOR j = 1 TO 88
				IF Game(j, -1) <> 0 THEN
					Game(j, -1) = a
					FichaVer j, -1
				END IF
			NEXT
			
			DO
			LOOP UNTIL TIMER > tim1! + .07

			'FOR K = 1 TO 3200: K1 = K: NEXT
			SWAP a, B
		NEXT
	END IF
  
	'displays score
	PointCount Level, Humano, Score(Humano), Score(PeCe)
	DisplMessage 0, "", 0
	total = Score(Humano) + Score(PeCe)
	LOCATE 4, 50: PRINT SPACE$(14); : LOCATE , 50
	COLOR 11: PRINT USING "###.#%  "; Score(Humano) / total * 100;
	COLOR 12: PRINT USING "###.#%"; Score(PeCe) / total * 100;
	LOCATE 5, 50: PRINT SPACE$(14); : LOCATE , 51
	COLOR 11: PRINT USING "##         "; Score(Humano);
	COLOR 12: PRINT USING "##"; Score(PeCe);
  
	'resets the blinking level of Game
	FOR i = 1 TO 88
			Game(i, -1) = 0
			FichaVer i, 0
	NEXT
	

END SUB

SUB DisplMessage (Player, txt$, pulse)
	'Displays message,waits for key and erases it
  
	CONST ltxt = 79
	CONST filatxt = 28
		 
	txt$ = LEFT$(txt$, ltxt)
	IF pulse = 1 THEN txt$ = txt$ + " Key or Click."
	txt$ = txt$ + SPACE$(79 - LEN(txt$))
	SELECT CASE Player
	CASE Humano
		COLOR 11
	CASE PeCe
		COLOR 12
	CASE ELSE
		COLOR Player
	END SELECT
	LOCATE filatxt, 1: PRINT txt$;
  
	IF pulse = 1 THEN
		DO
			a$ = INKEY$
			B = MouseInt(mget, dummy, dummy)
		LOOP UNTIL LEN(a$) OR B
		LOCATE filatxt, 1: PRINT SPACE$(ltxt);
	END IF

END SUB

SUB EvaluatePos (Level, punt, Player) STATIC
'Evaluates strategic value of the move, returns points

'Level    In    Level in Game() to evaluate
'punt     Out   Points obtained
'Jugador  In    Player

DIM contador(1 TO 88, 1 TO 4)  AS INTEGER
 
'resets counter array
ERASE contador

'evaluate lines in 4 directions
capa = 1: dir = 10
	FOR i = 1 TO 8: GOSUB valora: NEXT
capa = 2: dir = 1
	FOR i = 10 TO 80 STEP 10: GOSUB valora: NEXT
capa = 3: dir = 11
	FOR i = 0 TO 70 STEP 10: GOSUB valora: NEXT
	FOR i = 1 TO 7: GOSUB valora: NEXT
capa = 4: dir = 9
	FOR i = 19 TO 79 STEP 10: GOSUB valora: NEXT
	FOR i = 2 TO 9: GOSUB valora: NEXT
  
'at the end it adds up all values in contador
	punt = 0
	FOR i2 = 1 TO 8
		FOR i1 = 10 TO 80 STEP 10
		i = i1 + i2
		a = SGN(contador(i, 1)) * contador(i, 1) * contador(i, 2) * contador(i, 3) * contador(i, 4)
		punt = punt + a
		  ' LOCATE i1 / 10 + 10, i2 * 4 + 36: PRINT USING "+###"; a;
		NEXT
	NEXT
	punt = punt * Player
EXIT SUB

'evauates one line
'Tests for the ends of alignments of user's pieces.
'end in a limit BETTER THAN end by other players's pieces BETTER THAN free end
'i don't remember exactly how it works!!

valora:
	ini = i: prim = i: ult = i: sig = i
	vini = muro: vult = muro
	  DO
			sig = sig + dir
			vsig = Game(sig, Level)
			IF vult <> vsig THEN
				IF vult <> muro THEN
					IF vult <> 0 THEN
						punts = 1 * vult
					  
						'assigns ponts
						IF vini = muro OR vsig = muro THEN punts = 4 * vult
						IF vini = 0 AND vsig = 0 THEN punts = 2 * vult
						IF vini = -Player AND vsig = -Player THEN punts = 3 * vult
						FOR j = prim TO ult STEP dir
							contador(j, capa) = punts
						NEXT
					END IF
					ini = ult: vini = vult
				END IF
				prim = sig
			END IF
			ult = sig: vult = vsig
	  LOOP UNTIL vsig = muro
RETURN

END SUB

SUB FichaVer (posc, Level)
	'Puts a piece in the screen (can display levels other than 0, never used)
	' it must decode the one-dimensional position posc to row-column

	Player = Game(posc, Level)
	IF Player = 0 OR Player > 8 THEN EXIT SUB
	columna = (posc \ 10) * anchorej + dsplvert
	fila = (posc MOD 10) * anchorej + dsplhori
	SELECT CASE Player
	 CASE Humano
		CLOR = 9
	 CASE PeCe
		CLOR = 12
	 CASE ELSE
		CLOR = Player
	 END SELECT

	CIRCLE (fila, columna), 15, 16: PAINT (fila, columna), CLOR, 16
END SUB

SUB HumanMoves (Donde)
	'Human move, asks for input and does move, replay or exit as needed
	'Donde Output position of the move

	DisplMessage 0, "", 0
	DO
		a$ = INKEY$
		DisplMessage Humano, "You Play: Click position (Also R=Replay Q=Quit)", 0
		UserInput a$, x, y
		SELECT CASE UCASE$(a$)
		CASE "T"
			i = 0: a = 0: B = 0
			CLS : COLOR 4
			DEF SEG = VARSEG(otlotx)
		  
			a = VARPTR(otlotx): B = a + 1500
			FOR i = a TO B
				PRINT CHR$(PEEK(i));
			NEXT
		CASE "R"
			IF anterior = 1 THEN
				DisplMessage Humano, "To replay your last move", 1
				CopyGame -2, 0
				anterior = 0
				InitDisplay
				DisplayMove 0, 0
				pts = 0
			ELSE
				DisplMessage Humano, "No more saved moves", 1
			END IF
		CASE ELSE
			Donde = 10 * y + x
			LegalMove Donde, pts, 0, Humano, hjEsLegal
			IF pts = 0 THEN
				dummy = MouseInt(mshow, 0, 0)
				DisplMessage Humano, "Not a Legal Move:", 1
				dummy = MouseInt(mhide, 0, 0)
			END IF
			
			LOCATE 1, 51: COLOR 0: PRINT SPACE$(29)

		END SELECT
	LOOP UNTIL pts <> 0
		  CopyGame 0, -2
		  anterior = 1
END SUB

DEFSNG A-Z
SUB InitDisplay
'displays playground. No comment

	SCREEN 12
	COLOR 7
	CLS 2
	COLOR 2
	'lineas horiz
	FOR i = anchorej * 1 + dsplvert TO anchorej * 9 STEP anchorej
		LINE (anchorej, i)-STEP(anchorej * 8 + dsplvert, 0)
	NEXT
	'lineas vert
	FOR i = anchorej * 1 + dsplhori TO anchorej * 9 STEP anchorej
		LINE (i, anchorej)-STEP(0, anchorej * 8 + dsplhori)
	NEXT
  
	'bordes
  
	LINE (390, 20)-(520, 90), 7, B

	LOCATE 2, 55: PRINT "SCORE:"
	LOCATE 3, 52: COLOR 11: PRINT "YOU"; : LOCATE , 61: COLOR 12: PRINT "PC";

END SUB

DEFINT A-Z
SUB LegalMove (Donde, Ptosjugada, Profund, Player, LaHago) STATIC
'Tests for validity of a move or does it
'Donde      Input   Place to move
'PtosJugada Output  Nr Of captures 0 if its not a legal move
'Profund    Input   Level of Game() where move is done/tested
'Player     Input   Who moves
'LaHago     Input   hjEsLegal: only test for validity hjJuega: do the move
  
	Ptosjugada = 0
	 'If position occupied, exit
	IF Game(Donde, Profund) <> 0 THEN EXIT SUB
 
'para cada una de las 8 direcciones, comprobamos las fichas que se capturan
	FOR i = 0 TO 7
		j = Donde
		j1 = direcc(i)
		PtosLinea = 0                            'acumula capturas en esta direccion
		DO
			j = j + j1
			K = Game(j, Profund)
			PtosLinea = PtosLinea + 1
		LOOP UNTIL K <> -Player                 'hasta que no hay fichas contrarias
																  
'si terminamos en ficha propia no contigua a la inicial                                                 
		IF K = Player AND j <> Donde + j1 THEN
		  
'los puntos calculados son validos
			 Ptosjugada = Ptosjugada + PtosLinea - 1
			
'si puntua es valida      
			 IF Ptosjugada THEN
				 IF LaHago = hjEsLegal THEN
					EXIT SUB                         'si solo EsLegal? salir
			  
'si pretendemos hacer la jugada, la hacemos    
				 ELSEIF LaHago = hjJuega THEN
					FOR i1 = Donde TO j - j1 STEP j1
						Game(i1, Profund) = Player
						IF Profund = 0 THEN Game(i1, -1) = Player
					NEXT
				 END IF
			 END IF
		END IF
	NEXT
END SUB

SUB monitor (Level)
	'for debugging only, displays one level of Game()
  
	CLS
	FOR i = 1 TO 8
		FOR j = 10 TO 80 STEP 10
			LOCATE i, (j \ 10) * 3: PRINT Game(i + j, Level)
		NEXT
		NEXT


END SUB

FUNCTION MouseInt (func, fil, col)
'Mouse Interrupt rutines

'col,fil entrada Donde raton en mset
'col,fil salida Donde raton en mget,mpres,mrele
'col,fil entrada minx, maxx en mxlim
'col,fil entrada miny,maxy en mylim
'col entrada AND mask fil entrada XOR mask en mattr

'MouseInt devuelve:
'minit                         n§ botones.0 si no hay rat¢n
'mshow,mhide,mxlim,mylim,mset  nada
'mpres,mrel                    byte alto n§ pulsaciones, byte bajo botones
'mget                          botones

CONST mouStepH = 32
CONST mouStepV = 32
CONST MouOffH = 15
CONST MouOffV = 15




DIM regs AS RegTypeX

SELECT CASE func

CASE minit
	GOSUB MouseInt
	IF regs.ax THEN MouseInt = regs.bx
CASE mshow, mhide
	GOSUB MouseInt
CASE mget
	GOSUB MouseInt
	col = (regs.cx - MouOffV) \ mouStepV
	fil = (regs.dx - MouOffH) \ mouStepH
	MouseInt = regs.bx
CASE mset
	regs.cx = col * mouStepV + MouOffV + 12
	regs.dx = fil * mouStepH + MouOffH + 12
	GOSUB MouseInt
CASE mpres, mrele
	regs.bx = col
	GOSUB MouseInt
	col = regs.cx \ 8 + 1
	fil = regs.dx \ 8 + 1
	MouseInt = regs.bx * 256 + regs.ax
CASE mxlim
	regs.cx = (col - 1) * 8
	regs.dx = (fil - 1) * 8
	GOSUB MouseInt
CASE mylim
	regs.cx = (col - 1) * 8
	regs.dx = (fil - 1) * 8
	GOSUB MouseInt
CASE mattr
	regs.bx = 0
	regs.cx = col
	regs.dx = fil
	GOSUB MouseInt
END SELECT
EXIT FUNCTION

MouseInt:
	regs.ax = func
	CALL INTERRUPTX(&H33, regs, regs)
RETURN

END FUNCTION

SUB NextMove (Player, punt)
	'looks if the Player's next move can be done
	'if not, displays a message and asks for a key
	'does the next move
	'returns with the points obtained by the player (if 0, player has passed)

	SrchForValidMove 0, Player, posi             'Puede jugarse?
  
	IF posi = 0 THEN
	  
		SELECT CASE Player
		CASE PeCe
			DisplMessage Player, "PC passes", 1
		CASE Humano
			DisplMessage Player, "Human passes", 1
		END SELECT
		punt = 0

	ELSE                                         'permite la jugada por turnos
	  
		SELECT CASE Player
		CASE PeCe
			PCThinks pos1, pt, 1, PeCe
			IF pos1 = 0 THEN pos1 = posi
			
		CASE Humano
			HumanMoves pos1

		END SELECT
		LegalMove pos1, punt, 0, Player, hjJuega
		

	END IF
END SUB

SUB PCThinks (MejorPosic, ValorEstrtg, NivelCalculo, Player)
'  Recursive routine that ends up with the best move possible
'  MejorPosic  Out Best move found
'  ValorEstrtg Out Value of the best move        
'  NivelCalculoIn  Level in Game() and level of recursion
'  Player      In  Player that moves

	
	 'I'm not dead...
	IF NivelCalculo < PlayLevel THEN DisplMessage Player, "Evaluating,Level " + STR$(NivelCalculo), 0
	
	 'reset ranking of moves  
	REDIM rank(1 TO numrank)  AS elrank

	FOR i = 1 TO numrank: rank(i).punt = -32000: NEXT
 
	 'Fore each place in the playground
	FOR i = 11 TO 88                           '          'barre todo el tablero
		LegalMove i, Score, NivelCalculo - 1, Player, hjEsLegal

		  'if i'ts a legal position
		IF Score <> 0 THEN
			CopyGame NivelCalculo - 1, NivelCalculo
			LegalMove i, Score, NivelCalculo, Player, hjJuega
			PointCount NivelCalculo, Player, ptyo, ptcont
		  
		  'if other player without pieces, we won   
			IF ptcont = 0 THEN MejorPosic = i: ValorEstrtg = 32000: EXIT SUB
				
		  'evaluate position   
			EvaluatePos NivelCalculo, ValorEstrtg, Player
		  
			
		  'if position best than worse saved, swap and sort rank()      
			IF ValorEstrtg > rank(numrank).punt THEN
				rank(numrank).punt = ValorEstrtg
				rank(numrank).posi = i
				posj = numrank
				GOSUB bblsort
			END IF
		END IF
	NEXT

'
'if under max level, copy game in next level and recalls itself for each move
'in rank()

  
	IF NivelCalculo < PlayLevel THEN
	  
		FOR i = 1 TO numrank            'para cada una de las mejores jugadas
		  
			IF rank(i).punt = -32000 AND PlayLevel <> 1 AND i <> 1 THEN EXIT FOR
			'DebugRank NivelCalculo, rank(), rank(i).posi 'visualiza jugadas(debug)
		 
			CopyGame NivelCalculo - 1, NivelCalculo
			LegalMove rank(i).posi, dummy, NivelCalculo, Player, hjJuega
			PCThinks MejorPosic, ValorEstrtg, NivelCalculo + 1, -Player

			 'final value of a move is the reverse of the other player's  
			 'best next move
			rank(i).punt = -ValorEstrtg
		NEXT
			
		 'resort rank, the better move is the one that allows a worse
		 'next move for the other player
		FOR posj = 2 TO numrank
			GOSUB bblsort
		NEXT
	END IF
  
	'DebugRank NivelCalculo, rank(), 0
 
	 'returns first entry in rank()
	MejorPosic = rank(1).posi
	ValorEstrtg = rank(1).punt
EXIT SUB

'small bubblesort routine to sort best moves
bblsort:
	IF posj = 1 THEN EXIT SUB
 
	FOR temp = posj TO 2 STEP -1
		IF rank(temp).punt > rank(temp - 1).punt THEN
			SWAP rank(temp), rank(temp - 1)
		END IF
	NEXT
RETURN
END SUB

SUB PointCount (Level, Player, ptosyo, ptoscont)
	ptosyo = 0: ptoscont = 0
	FOR i = 10 TO 80 STEP 10
	FOR j = 1 TO 8
		SELECT CASE Game(i + j, Level)
		CASE Player
			ptosyo = ptosyo + 1
		CASE -Player
			ptoscont = ptoscont + 1
		END SELECT
	NEXT
	NEXT


END SUB

SUB Presentacion
	SCREEN 12
	CLS
	LOCATE 2, 28: COLOR 14: PRINT "O T H E L L O   "
	COLOR 7
	LOCATE 3, 25: PRINT "Antoni Gual Via 1997 "
	COLOR 15
  
END SUB

SUB SrchForValidMove (Profund, Player, posi) 'devuelve 1¦ tirada valida, 0 si no hay
	
	posi = 10
  
	DO
		posi = posi + 1
		LegalMove posi, pts, Profund, Player, hjEsLegal
	LOOP UNTIL pts <> 0 OR posi = 89
  
	IF posi = 89 THEN posi = 0
END SUB

SUB UserInput (a$, x, y)
'Takes input from user:cursor keys or mouse
'A$ Output LastKey Pressed
'X  Output Column Selected
'Y  Output Row Selected


	STATIC cur1 AS INTEGER, cur2 AS INTEGER
	dummy = MouseInt(mset, cur2, cur1)
	dummy = MouseInt(mshow, 0, 0)
	a$ = ""
	DO
		a$ = INKEY$
		SELECT CASE RIGHT$(a$, 1)
		CASE "q", "Q"                    'quit
		 END
		CASE "r", "R"
		  dummy = MouseInt(mhide, 0, 0)  'repeat
		  EXIT SUB
		CASE "K"
		 cur1 = cur1 - 1
		 IF cur1 < 1 THEN cur1 = 1
		 dummy = MouseInt(mset, cur2, cur1)
		CASE "H"
		  cur2 = cur2 - 1
		 IF cur2 < 1 THEN cur2 = 1
		 dummy = MouseInt(mset, cur2, cur1)
		CASE "M"
		  cur1 = cur1 + 1
		  IF cur1 > 8 THEN cur1 = 8
		 dummy = MouseInt(mset, cur2, cur1)
		CASE "P"
		  cur2 = cur2 + 1
		  IF cur2 > 8 THEN cur2 = 8
		 dummy = MouseInt(mset, cur2, cur1)
		END SELECT
		 
		B = MouseInt(mget, mf, mc)
		IF B THEN x = mc: y = mf
	LOOP UNTIL B OR a$ = CHR$(13)
	
	dummy = MouseInt(mhide, 0, 0)
	IF B = 0 THEN x = cur1: y = cur2
  IF x > 8 THEN x = 8
  IF y > 8 THEN y = 8
  cur1 = x: cur2 = y
END SUB
