using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using JJC.Psharp.Lang; using JJC.Psharp.Predicates; namespace ox4 { /// /// P# demonstration program. /// 22 February 2002. /// /// Web Application for a 4 x 4 noughts and crosses game. /// Each move can be taken by either the user or the computer. /// The computer's moves are chosen by a Prolog backend. /// public class Ox4Form : System.Web.UI.Page { protected System.Web.UI.WebControls.Button Cell1, Cell2, Cell3, Cell4, Cell5, Cell6, Cell7, Cell8, Cell9, Cell10, Cell11, Cell12, Cell13, Cell14, Cell15, Cell16; protected System.Web.UI.WebControls.Button ResetButton, MoveButton; protected System.Web.UI.WebControls.Label Title; private bool winLock { get { return (bool)Session.Contents[ "winLock" ]; } set { Session.Contents[ "winLock" ] = value; } } private Term currentBoard { get { return (Term)Session.Contents[ "currentBoard" ]; } set { Session.Contents[ "currentBoard" ] = value; } } private SymbolTerm currentPlayer { get { return (SymbolTerm)Session.Contents[ "currentPlayer" ]; } set { Session.Contents[ "currentPlayer" ] = value; } } private bool haveInited { get { return (bool)Session.Contents[ "haveInited" ]; } set { Session.Contents[ "haveInited" ] = value; } } protected System.Web.UI.WebControls.Button[] Cells; private void Page_Load(object sender, System.EventArgs e) { Cells = new Button[] { Cell1, Cell2, Cell3, Cell4, Cell5, Cell6, Cell7, Cell8, Cell9, Cell10, Cell11, Cell12, Cell13, Cell14, Cell15, Cell16 }; if( !haveInited ) { haveInited = true; ResetBoard(); } } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.ResetButton.Click += new System.EventHandler(this.ResetButton_Click); this.Cell16.Click += new System.EventHandler(this.Cell16_Click); this.Cell15.Click += new System.EventHandler(this.Cell15_Click); this.Cell14.Click += new System.EventHandler(this.Cell14_Click); this.Cell13.Click += new System.EventHandler(this.Cell13_Click); this.Cell12.Click += new System.EventHandler(this.Cell12_Click); this.Cell11.Click += new System.EventHandler(this.Cell11_Click); this.Cell10.Click += new System.EventHandler(this.Cell10_Click); this.Cell9.Click += new System.EventHandler(this.Cell9_Click); this.Cell8.Click += new System.EventHandler(this.Cell8_Click); this.Cell7.Click += new System.EventHandler(this.Cell7_Click); this.Cell6.Click += new System.EventHandler(this.Cell6_Click); this.Cell5.Click += new System.EventHandler(this.Cell5_Click); this.Cell4.Click += new System.EventHandler(this.Cell4_Click); this.Cell3.Click += new System.EventHandler(this.Cell3_Click); this.Cell2.Click += new System.EventHandler(this.Cell2_Click); this.MoveButton.Click += new System.EventHandler(this.MoveButton_Click); this.Cell1.Click += new System.EventHandler(this.Cell1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion /* Utilities */ /* --------- */ private void SwapPlayer( ) { currentPlayer = currentPlayer.name.Equals( "x" ) ? SymbolTerm.makeSymbol( "o", 0 ) : SymbolTerm.makeSymbol( "x", 0 ); } private string Convert( string s ) { return s.Equals( "b" ) ? " " : s.Equals( "o" ) ? "O" : s.Equals( "x" ) ? "X" : "ERROR"; } /* Drawing */ /* ------- */ private void ResetButtonBackgrounds( ) { foreach( Button b in Cells ) b.BackColor = Color.Beige; } private void DrawWin( ListTerm newBoard ) { Term result = newBoard; Term elm; for (int i = 0; i < 16; i++) { elm = ((ListTerm)result).car.dereference(); if( Convert( elm.ToString() ).Equals( "O" ) ) { Cells[ i ].BackColor = Color.Crimson; winLock = true; } result = ((ListTerm)result).cdr.dereference(); if( !( result is ListTerm ) ) break; } } private void DrawBoard( ListTerm newBoard ) { Term result = newBoard; Term elm; for (int i = 0; i < 16; i++) { elm = ((ListTerm)result).car.dereference(); Cells[ i ].Text = Convert( elm.ToString() ); result = ((ListTerm)result).cdr.dereference(); if( !( result is ListTerm ) ) break; } } /* Find which cell was clicked */ /* --------------------------- */ private void cellClick( object sender, System.EventArgs e ) { int cell = -1; for( int i = 1; i <= 16; ++i ) if( Cells[ i - 1 ] == sender ) cell = i; if( cell == -1 ) throw new Exception( "Internal Error: unexpected cell" ); if( !winLock ) HumanMove( cell ); } /* Calls into Prolog */ /* ----------------- */ public void ResetBoard( ) { ResetButtonBackgrounds( ); winLock = false; currentPlayer = SymbolTerm.makeSymbol( "x", 0 ); PrologInterface sharp = new PrologInterface( ); Term a1 = new VariableTerm( ); Predicate reset = new Blank_1( a1, new ReturnCs( sharp ) ); sharp.setPredicate( reset ); sharp.call( ); Term result = a1.dereference(); if ( !result.isList() || ((ListTerm)result).length() != 16 ){ Console.WriteLine("Invalid result!"); return; } currentBoard = a1.dereference(); DrawBoard( (ListTerm)( currentBoard ) ); } private void ComputerMove( ) { PrologInterface sharp = new PrologInterface( ); Term a2 = new VariableTerm( ); Predicate compMove = new Rule_3( currentPlayer, currentBoard, a2, new ReturnCs( sharp ) ); sharp.setPredicate( compMove ); sharp.call( ); Term result = a2.dereference(); if ( !result.isList() || ((ListTerm)result).length() != 16 ){ Console.WriteLine("Invalid result!"); return; } currentBoard = a2.dereference(); DrawBoard( (ListTerm)currentBoard ); SwapPlayer( ); CheckForWinningLine( ); } private void CheckForWinningLine( ) { PrologInterface sharp = new PrologInterface( ); Term a2 = new VariableTerm( ); Predicate win = new WinningLine_2( currentBoard, a2, new ReturnCs( sharp ) ); sharp.setPredicate( win ); sharp.call( ); Term result = a2.dereference(); if ( !result.isList() || ((ListTerm)result).length() != 16 ){ return; } DrawWin( (ListTerm)result ); } private void HumanMove( int position ) { PrologInterface sharp = new PrologInterface( ); Term a1 = new IntegerTerm( position ); Term a2 = new VariableTerm( ); Predicate humanMove = new PlayInGivenPlace_4( currentPlayer, currentBoard, a2, a1, new ReturnCs( sharp ) ); sharp.setPredicate( humanMove ); sharp.call( ); Term result = a2.dereference(); if ( !result.isList() || ((ListTerm)result).length() != 16 ){ Console.WriteLine("Invalid result!"); return; } currentBoard = a2.dereference(); DrawBoard( (ListTerm)currentBoard ); SwapPlayer( ); CheckForWinningLine(); } /* Button Clicks */ /* ------------- */ private void Cell1_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell2_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell3_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell4_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell5_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell6_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell7_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell8_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell9_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell10_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell11_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell12_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell13_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell14_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell15_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void Cell16_Click(object sender, System.EventArgs e) { cellClick( sender, e ); } private void ResetButton_Click(object sender, System.EventArgs e) { ResetBoard(); } private void MoveButton_Click(object sender, System.EventArgs e) { if( !winLock ) ComputerMove( ); } } }