miércoles, 30 de marzo de 2011

Código del Juego del Gato o Tic Tac Toe C#

Este código lo utilice para implementar un tic tac toe con C# para Windows Phone 7.






Código fuente



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{
    /// <summary>
    ///
    /// </summary>
    public enum Players
    {
        Human = 4,
        Computer = 7,
        NoBody = 0
    }
    /// <summary>
    ///
    /// </summary>
    public class TicTacToe
    {

        int currentIndex=0;     

        int[] winnerCells = new int[3] { 0,0,0};

        int[] maze = new int[9] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        /// <summary>
        /// Cell for the last move
        /// </summary>
        public int LastMove
        {
            get
            {
                return currentIndex;
            }
        }

        /// <summary>
        /// Winner cells
        /// </summary>
        public int[] WinnerCells {
            get {
                return winnerCells;
            }
        }
        /// <summary>
        /// Game Maze
        /// </summary>
        public int[] Maze {
            get {
                return maze;
            }
        }
        /// <summary>
        /// Determines if the game it's over
        /// </summary>
        public bool ItIsOver {
            get {
                bool r = false;
                int c = 0;
                for (int i = 0; i < maze.Length; i++) {
                    if (maze[i] != (int) Players.NoBody ) {
                        c++;
                    }            
               
                }
                r = c == maze.Length;

                return r;

            }
        }
        /// <summary>
        /// Reset the game
        /// </summary>
        public void Reset()
        {
            for (int i = 0; i < maze.Length; i++)
                maze[i] = 0;
            for (int i = 0; i < winnerCells.Length; i++)
                winnerCells[i] = 0;
            currentIndex = -1;
        }
        /// <summary>
        /// Default Constructor
        /// </summary>
        public TicTacToe()
        {
            Reset();
        }
        /// <summary>
        /// Find who wins
        /// </summary>
        /// <returns></returns>
        public Players WhoWins()
        {
            Players result = Players.NoBody;
            bool win = false;
            int winner = 0;


            GetWinner(ref win, ref winner, 0, 1, 2, 3, 3, 3, 3);

            if (!win)
            {

                GetWinner(ref win, ref winner, 0, 3, 6, 1, 1, 1, 3);

                if (!win)
                {

                    GetWinner(ref win, ref winner, 0, 4, 8, 2, 0, -2, 2);
                }
            }

            if (win)
            {

                if (winner == (int)Players.Computer)
                    result = Players.Computer;
                else
                    if (winner == (int)Players.Human)
                        result = Players.Human;
            }
            else
            {
                result = Players.NoBody;
            }

            return result;
        }
        /// <summary>
        /// Find who wins
        /// </summary>
        /// <param name="win"></param>
        /// <param name="winner"></param>
        /// <param name="c1">cell 1</param>
        /// <param name="c2">cell 2</param>
        /// <param name="c3">cell 3</param>
        /// <param name="d1">delta change in cell 1</param>
        /// <param name="d2">delta change in cell 2</param>
        /// <param name="d3">delta change in cell 3</param>
        /// <param name="times">times to do the search this can be done 3 or 2 times</param>
        private void GetWinner(ref bool win, ref int winner, int c1, int c2, int c3, int d1, int d2, int d3, int times)
        {

            for (int i = 0; i < times && !win; i++)
            {
                if (maze[c1] != (int)Players.NoBody && (maze[c1] == maze[c2]) && (maze[c2] == maze[c3]))
                {
                    winner = maze[c1];
                    currentIndex = c1;
                    win = true;
                    winnerCells[0] = c1;
                    winnerCells[1] = c2;
                    winnerCells[2] = c3;
                }
                else
                {

                    c1 += d1;
                    c2 += d2;
                    c3 += d3;
                }
            }
        }
        /// <summary>
        /// Mark a cell
        /// </summary>
        /// <param name="number">number of cell to be marked</param>
        /// <param name="player">player who marks a cell</param>
        /// <returns></returns>
        public bool Mark(int index, Players player)
        {
            bool result = false;
           
            if (index < 0 && index > 8)
                throw new Exception("Index out of bounds");
           
            if (maze[index] == (int) Players.NoBody )
            {
                maze[index] = (int)player;
                result = true;
            }

            return result;
        }
        /// <summary>
        /// Mark a cell
        /// </summary>
        /// <param name="row">row number</param>
        /// <param name="col">column number</param>
        /// <param name="player">player who marks a cell</param>
        /// <returns></returns>
        public bool Mark(int row, int col, Players player)
        {
            bool result = false;
            int index = 0;

            if (row < 0 && row > 2)
                throw new Exception("Row out of bounds");

            if (col < 0 && col > 2)
                throw new Exception("Column out of bounds");

            index = row * 3 + col;
            if (maze[index] == (int)Players.NoBody)
            {
                maze[index] = (int)player;
                result = true;
            }

            return result;
        }
        /// <summary>
        /// Invokes a move strategy
        /// </summary>
        public void Move()
        {
            if (!TryToWin(0, 1, 2, 3, 3, 3, 3))
            {
                if (!TryToWin(0, 3, 6, 1, 1, 1, 3))
                {
                    if (!TryToWin(0, 4, 8, 2, 0, -2, 2))
                    {
                        if (!BlockEnemy(0, 1, 2, 3, 3, 3, 3))
                        {
                            if (!BlockEnemy(0, 3, 6, 1, 1, 1, 3))
                            {
                                if (!BlockEnemy(0, 4, 8, 2, 0, -2, 2))
                                {
                      
                                    DoMove();

                                }

                            }
                        }

                    }
                }
            }
        }
        /// <summary>
        /// Do a move. This is done when it is not posible to do a winning move or it is not needed to block the enemy .
        /// </summary>
        /// <param name="c1">cell 1</param>
        /// <param name="c2">cell 2</param>
        /// <param name="c3">cell 3</param>
        /// <param name="d1">delta change in cell 1</param>
        /// <param name="d2">delta change in cell 2</param>
        /// <param name="d3">delta change in cell 3</param>
        /// <param name="times">times to do the search this can be done 3 or 2 times</param>
        /// <returns></returns>
        private bool DoMove()
        {
            bool result = false;

            if (maze[0] == (int)Players.Computer && maze[1] == (int)Players.NoBody && maze[2] == (int)Players.NoBody)
            {
                maze[1] = (int)Players.Computer;
                currentIndex = 1;
                result = true;
            }
            else
                if (maze[0] == (int)Players.Computer && maze[3] == (int)Players.NoBody && maze[6] == (int)Players.NoBody)
                {
                    maze[3] = (int)Players.Computer;
                    currentIndex = 3;
                    result = true;
                }
                else
                    if (maze[0] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[8] == (int)Players.NoBody)
                    {
                        maze[4] = (int)Players.Computer;
                        currentIndex = 4;
                        result = true;
                    }
                    else
                        if (maze[1] == (int)Players.Computer && maze[0] == (int)Players.NoBody && maze[2] == (int)Players.NoBody)
                        {
                            maze[0] = (int)Players.Computer;
                            currentIndex = 0;
                            result = true;
                        }
                        else
                            if (maze[1] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[7] == (int)Players.NoBody)
                            {
                                maze[4] = (int)Players.Computer;
                                currentIndex = 4;
                                result = true;
                            }
                            else
                                if (maze[2] == (int)Players.Computer && maze[0] == (int)Players.NoBody && maze[1] == (int)Players.NoBody)
                                {
                                    maze[0] = (int)Players.Computer;
                                    currentIndex = 0;
                                    result = true;
                                }
                                else
                                    if (maze[2] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[6] == (int)Players.NoBody)
                                    {
                                        maze[4] = (int)Players.Computer;
                                        currentIndex = 4;
                                        result = true;
                                    }
                                    else
                                        if (maze[2] == (int)Players.Computer && maze[5] == (int)Players.NoBody && maze[8] == (int)Players.NoBody)
                                        {
                                            maze[5] = (int)Players.Computer;
                                            currentIndex = 5;
                                            result = true;
                                        }
                                        else
                                            if (maze[3] == (int)Players.Computer && maze[0] == (int)Players.NoBody && maze[6] == (int)Players.NoBody)
                                            {
                                                maze[0] = (int)Players.Computer;
                                                currentIndex = 0;
                                                result = true;
                                            }
                                            else
                                                if (maze[3] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[5] == (int)Players.NoBody)
                                                {
                                                    maze[4] = (int)Players.Computer;
                                                    currentIndex = 4;
                                                    result = true;
                                                }
                                                else
                                                    if (maze[5] == (int)Players.Computer && maze[3] == (int)Players.NoBody && maze[4] == (int)Players.NoBody)
                                                    {
                                                        maze[3] = (int)Players.Computer;
                                                        currentIndex = 3;
                                                        result = true;
                                                    }
                                                    else
                                                        if (maze[5] == (int)Players.Computer && maze[2] == (int)Players.NoBody && maze[8] == (int)Players.NoBody)
                                                        {
                                                            maze[2] = (int)Players.Computer;
                                                            currentIndex = 2;
                                                            result = true;
                                                        }
                                                        else
                                                            if (maze[6] == (int)Players.Computer && maze[7] == (int)Players.NoBody && maze[8] == (int)Players.NoBody)
                                                            {
                                                                maze[7] = (int)Players.Computer;
                                                                currentIndex = 7;
                                                                result = true;
                                                            }
                                                            else
                                                                if (maze[6] == (int)Players.Computer && maze[0] == (int)Players.NoBody && maze[3] == (int)Players.NoBody)
                                                                {
                                                                    maze[0] = (int)Players.Computer;
                                                                    currentIndex = 0;
                                                                    result = true;
                                                                }
                                                                else
                                                                    if (maze[6] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[2] == (int)Players.NoBody)
                                                                    {
                                                                        maze[4] = (int)Players.Computer;
                                                                        currentIndex = 4;
                                                                        result = true;
                                                                    }
                                                                    else
                                                                        if (maze[7] == (int)Players.Computer && maze[6] == (int)Players.NoBody && maze[8] == (int)Players.NoBody)
                                                                        {
                                                                            maze[6] = (int)Players.Computer;
                                                                            currentIndex = 6;
                                                                            result = true;
                                                                        }
                                                                        else
                                                                            if (maze[7] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[1] == (int)Players.NoBody)
                                                                            {
                                                                                maze[0] = (int)Players.Computer;
                                                                                currentIndex = 0;
                                                                                result = true;
                                                                            }
                                                                            else
                                                                                if (maze[8] == (int)Players.Computer && maze[2] == (int)Players.NoBody && maze[5] == (int)Players.NoBody)
                                                                                {
                                                                                    maze[2] = (int)Players.Computer;
                                                                                    currentIndex = 2;
                                                                                    result = true;
                                                                                }
                                                                                else
                                                                                    if (maze[8] == (int)Players.Computer && maze[4] == (int)Players.NoBody && maze[0] == (int)Players.NoBody)
                                                                                    {
                                                                                        maze[4] = (int)Players.Computer;
                                                                                        currentIndex = 4;
                                                                                        result = true;
                                                                                    }
                                                                                    else
                                                                                        if (maze[8] == (int)Players.Computer && maze[6] == (int)Players.NoBody && maze[7] == (int)Players.NoBody)
                                                                                        {
                                                                                            maze[6] = (int)Players.Computer;
                                                                                            currentIndex = 6;
                                                                                            result = true;
                                                                                        }

            if (!result)
            {
                int[] seq = new int[] { 4, 2, 6, 8, 3, 7, 0, 5, 1 };
                for (int i = 0; i < seq.Length && !result; i++)
                {
                    result = maze[seq[i]] == (int)Players.NoBody;
                    if (result)
                    {
                        maze[seq[i]] = (int)Players.Computer;
                        currentIndex = seq[i];
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Try to block the next posible winning move from the human
        /// </summary>
        /// <param name="c1">cell 1</param>
        /// <param name="c2">cell 2</param>
        /// <param name="c3">cell 3</param>
        /// <param name="d1">delta change in cell 1</param>
        /// <param name="d2">delta change in cell 2</param>
        /// <param name="d3">delta change in cell 3</param>
        /// <param name="times">times to do the search this can be done 3 or 2 times</param>
        /// <returns></returns>
        private bool BlockEnemy(int c1, int c2, int c3, int d1, int d2, int d3, int times)
        {
            bool result = false;

            for (int i = 0; i < times && !result; i++)
            {
                if ((maze[c1] == maze[c2] && maze[c1] == (int)Players.Human && maze[c3] == (int)Players.NoBody))
                {
                    maze[c3] = (int)Players.Computer;
                    currentIndex = c3;
                    result = true;
                }
                else
                    if ((maze[c1] == maze[c3] && maze[c1] == (int)Players.Human && maze[c2] == (int)Players.NoBody))
                    {
                        maze[c2] = (int)Players.Computer;
                        currentIndex = c2;
                        result = true;
                    }
                    else
                        if ((maze[c2] == maze[c3] && maze[c2] == (int)Players.Human && maze[c1] == (int)Players.NoBody))
                        {
                            maze[c1] = (int)Players.Computer;
                            currentIndex = c1;
                            result = true;
                        }
                        else
                        {
                            c1 += d1;
                            c2 += d2;
                            c3 += d3;
                        }

            }

            return result;
        }
        /// <summary>
        /// Try to do a winning move, finding two cells with the computer player mark
        /// and trying to put a winning mark into an empty cell.
        ///
        /// The cells are based, on a linear vector with 9 positions from 0..8
        /// </summary>
        /// <param name="c1">cell 1</param>
        /// <param name="c2">cell 2</param>
        /// <param name="c3">cell 3</param>
        /// <param name="d1">delta change in cell 1</param>
        /// <param name="d2">delta change in cell 2</param>
        /// <param name="d3">delta change in cell 3</param>
        /// <param name="times">times to do the search this can be done 3 or 2 times</param>
        /// <returns></returns>
        private bool TryToWin(int c1, int c2, int c3, int d1, int d2, int d3, int times)
        {
            bool result = false;

            for (int i = 0; i < times && !result; i++)
            {
                if ((maze[c1] == maze[c2] && maze[c1] == (int)Players.Computer && maze[c3] == (int)Players.NoBody))
                {
                    maze[c3] = (int)Players.Computer;
                    currentIndex = c3;
                    result = true;
                }
                else
                    if ((maze[c1] == maze[c3] && maze[c1] == (int)Players.Computer && maze[c2] == (int)Players.NoBody))
                    {
                        maze[c2] = (int)Players.Computer;
                        currentIndex = c2;
                        result = true;
                    }
                    else
                        if ((maze[c2] == maze[c3] && maze[c2] == (int)Players.Computer && maze[c1] == (int)Players.NoBody))
                        {
                            maze[c1] = (int)Players.Computer;
                            currentIndex = c1;
                            result = true;
                        }
                        else
                        {
                            c1 += d1;
                            c2 += d2;
                            c3 += d3;
                        }

            }

            return result;
        }

    }
}


 Código fuente front-end C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Game;

namespace ElGato
{
    public partial class MainPage : PhoneApplicationPage
    {
        private Line line = null;
        private bool ItsOver = false;
        private Game.TicTacToe gato = new Game.TicTacToe();
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void btn8_Click(object sender, RoutedEventArgs e)
        {
            if (ItsOver)
            {
                MessageBox.Show("JUEGO TERMINADO!!!");
                return;
            }

            if (sender is Button) {

                string value = Convert.ToString((sender as Button).Content);

                if (
                   
                    value != "X" && value != "O"
                    )

                {
                    (sender as Button).Content = "X";
                    

                    int cell = Convert.ToInt32 ((sender as Button).Name.Replace("btn", ""));
                    gato.Mark(cell, Players.Human);
                    gato.Move();

                    switch (gato.LastMove) {
                        case 0:
                            btn0.Content = "O";
                            break;
                        case 1:
                            btn1.Content = "O";
                            break;
                        case 2:
                            btn2.Content = "O";
                            break;
                        case 3:
                            btn3.Content = "O";
                            break;
                        case 4:
                            btn4.Content = "O";
                            break;
                        case 5:
                            btn5.Content = "O";
                            break;
                        case 6:
                            btn6.Content = "O";
                            break;
                        case 7:
                            btn7.Content = "O";
                            break;
                        case 8:
                            btn8.Content = "O";
                            break;
                        default:
                            break;
                    }

                    switch (gato.WhoWins()) {
                        case Players.Computer :
                            ItsOver = true;


                            ShowLine();

                            txtMsg.Text = "FIN DEL JUEGO (PERDISTE)";
                            break;
                        case Players.Human :
                           
                            ItsOver = true;

                            ShowLine();

                            txtMsg.Text = "FIN DEL JUEGO (GANASTE)";
                           
                            break;
                        default:
                            if (gato.ItIsOver) {
                                ItsOver = true;
                               
                                txtMsg.Text = "FIN DEL JUEGO (EMPATE)";
                            }
                            break;
                    }

                   
               
                }
            }
        }

        private void ShowLine() {
            switch (gato.WinnerCells[0]) {

                case 0:
                    line.X1 = 107;
                    line.Y1 =280;
                    break;
                case 1:
                    line.X1 = 241;
                    line.Y1 =280;
                    break;
                case 2:
                    line.X1 = 354;
                    line.Y1 =280;
                    break;
                case 3:
                    line.X1 = 107;
                    line.Y1 =423;
                    break;
                case 4:
                    line.X1 = 241;
                    line.Y1 =423;
                    break;
                case 5:
                    line.X1 = 354;
                    line.Y1 =423;
                    break;
                case 6:
                    line.X1 = 107;
                    line.Y1 =550;
                    break;
                case 7:
                    line.X1 = 241;
                    line.Y1 =550;
                    break;
                case 8:
                    line.X1 = 354;
                    line.Y1 =550;
                    break;
                default :
                    break;
            }

            switch (gato.WinnerCells[2])
            {

                case 0:
                    line.X2 = 107;
                    line.Y2 = 280;
                    break;
                case 1:
                    line.X2 = 241;
                    line.Y2 = 280;
                    break;
                case 2:
                    line.X2 = 354;
                    line.Y2 = 280;
                    break;
                case 3:
                    line.X2 = 107;
                    line.Y2 = 423;
                    break;
                case 4:
                    line.X2 = 241;
                    line.Y2 = 423;
                    break;
                case 5:
                    line.X2 = 354;
                    line.Y2 = 423;
                    break;
                case 6:
                    line.X2 = 107;
                    line.Y2 = 550;
                    break;
                case 7:
                    line.X2 = 241;
                    line.Y2 = 550;
                    break;
                case 8:
                    line.X2 = 354;
                    line.Y2 = 550;
                    break;
                default:
                    break;
            }
            line.Visibility = System.Windows.Visibility.Visible;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
                gato.Reset();
                ItsOver = false;
                btn0.Content = string.Empty ;
                btn1.Content = string.Empty;
                btn2.Content = string.Empty;
                btn3.Content = string.Empty;
                btn4.Content = string.Empty;
                btn5.Content = string.Empty;
                btn6.Content = string.Empty;
                btn7.Content = string.Empty;
                btn8.Content = string.Empty;
                txtMsg.Text = string.Empty;

                line.Visibility = System.Windows.Visibility.Collapsed;
               

        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            line = new Line();
            line.Stroke = new SolidColorBrush(Colors.Red);
            line.StrokeThickness = 15;                           
                       
            this.defaultView.Children.Add(line);

        }
    }
}


 Código fuente front-end XAML

<phone:PhoneApplicationPage
    x:Class="ElGato.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded">

    <Canvas Name="defaultView">
        <Button Canvas.Left="37" Canvas.Top="230" Height="150" Name="btn0" Width="150" FontSize="72" Click="btn8_Click" BorderThickness="0,0,3,3" />
        <Button Canvas.Left="160" Canvas.Top="230" FontSize="72" Height="150" Name="btn1" Width="150" Click="btn8_Click" BorderThickness="3,0,3,3" />
        <Button Canvas.Left="284" Canvas.Top="230" FontSize="72" Height="150" Name="btn2" Width="150" Click="btn8_Click" BorderThickness="3,0,0,3" />
        <Button Canvas.Left="37" Canvas.Top="353" FontSize="72" Height="150" Name="btn3" Width="150" Click="btn8_Click" BorderThickness="0,3,3,3" />
        <Button Canvas.Left="161" Canvas.Top="353" FontSize="72" Height="150" Name="btn4" Width="150" Click="btn8_Click" />
        <Button Canvas.Left="284" Canvas.Top="353" FontSize="72" Height="150" Name="btn5" Width="150" Click="btn8_Click" BorderThickness="3,3,0,3" />
        <Button Canvas.Left="37" Canvas.Top="476" FontSize="72" Height="150" Name="btn6" Width="150" Click="btn8_Click" BorderThickness="0,3,3,0" />
        <Button Canvas.Left="161" Canvas.Top="476" FontSize="72" Height="150" Name="btn7" Width="150" Click="btn8_Click" BorderThickness="3,3,3,0" />
        <Button Canvas.Left="284" Canvas.Top="476" FontSize="72" Height="150" Name="btn8" Width="150" Click="btn8_Click" BorderThickness="3,3,0,0" />
        <Button Canvas.Left="26" Canvas.Top="644" Content="JuGar de NueVo" Height="74" Name="button1" Width="413" BorderThickness="2" Background="RoyalBlue" Click="button1_Click" />
        <TextBlock Canvas.Left="12" Canvas.Top="36" Height="103" Name="textBlock1" Text="El JuGO Del GaTO" Width="302" FontSize="40" />
        <Image Canvas.Left="334" Canvas.Top="36" Height="124" Name="image1" Stretch="Fill" Width="134" Source="/ElGato;component/Images/cat-icon-small.png" />
        <TextBlock Canvas.Left="38" Canvas.Top="166" Height="57" Name="txtMsg" Text="" Width="401" Foreground="Red" FontWeight="Bold" />
    </Canvas>

</phone:PhoneApplicationPage>

Transacciones Fiori

  /UI2/CACHE Register service for UI2 cache use /UI2/CACHE_DEL Delete cache entries /UI2/CHIP Chip Registration /UI2/CUST Customizing of UI ...