示例#1
0
 // If gameOver is true in state then game is over and display the winning text and appropriate colors
 void Update()
 {
     if (screenShown == false && OthelloGame.gameOver == true)
     {
         winnerText.GetComponent <Text>().text = "Winner: " + OthelloGame.GetWinner().ToUpper();
         if (OthelloGame.GetWinner() == "white")
         {
             winnerText.GetComponent <Text>().color            = Color.white;
             gameOverText.GetComponent <Text>().color          = Color.white;
             backgroundCube.GetComponent <Renderer>().material = blue;
         }
         else if (OthelloGame.GetWinner() == "black")
         {
             winnerText.GetComponent <Text>().color            = Color.black;
             gameOverText.GetComponent <Text>().color          = Color.black;
             backgroundCube.GetComponent <Renderer>().material = red;
         }
         else
         {
             winnerText.GetComponent <Text>().color            = Color.white;
             gameOverText.GetComponent <Text>().color          = Color.white;
             backgroundCube.GetComponent <Renderer>().material = squareGreen;
         }
         restartScreen.SetActive(true);
         screenShown = true;
     }
 }
示例#2
0
        private void SetupBoard()
        {
            _myGame            = new OthelloGame();
            _minMaxAgent       = new MinMaxAgent();
            _boardPanels       = new PiecePanel[OthelloGame.BOARD_SIZE, OthelloGame.BOARD_SIZE];
            _currentViewedMove = 0;
            int tileSize = ((Size.Width > Size.Height) ? Size.Height - 45 : Size.Width - 45) / OthelloGame.BOARD_SIZE;

            for (int i = 0; i < OthelloGame.BOARD_SIZE; i++)
            {
                for (int j = 0; j < OthelloGame.BOARD_SIZE; j++)
                {
                    var newPanel = new PiecePanel(new int[] { i, j })
                    {
                        Size     = new Size(tileSize, tileSize),
                        Location = new Point(tileSize * i, tileSize * j)
                    };

                    newPanel.MouseClick += new MouseEventHandler(OthelloPeice_Click);
                    Controls.Add(newPanel);
                    _boardPanels[i, j] = newPanel;

                    Color panelcolor = Color.Red;
                    if (BoardColorDictionary.BoardStateColors.TryGetValue(_myGame.GetBoard()[i, j], out panelcolor))
                    {
                        _boardPanels[i, j].ReColor(panelcolor);
                    }
                }
            }
        }
示例#3
0
 /// <summary>
 /// The main entry point for the application.
 /// </summary>
 static void Main(string[] args)
 {
     using (OthelloGame game = new OthelloGame())
     {
         game.Run();
     }
 }
示例#4
0
        public override byte[] MakeMove(OthelloGame game, BoardStates player)
        {
            byte[]        bestMove = new byte[] { byte.MaxValue, byte.MaxValue };
            List <byte[]> moves    = game.GetPossiblePlayList();

            double bestScore = int.MinValue + 1;

            if (game.GetPieceCount(BoardStates.empty) > 58)//first two moves, don't compute
            {
                return(OpeningMove(player, game));
            }
            else if (moves.Count == 1) //don't compute if there is only 1 move
            {
                return(moves[0]);
            }

            foreach (byte[] move in moves)
            {
                OthelloGame testGame = game.DeepCopy();
                testGame.MakeMove(move);
                double thisScore = EvaluateBoard(testGame, player);
                if (thisScore > bestScore)
                {
                    bestScore = thisScore;
                    bestMove  = move;
                }
            }
            if ((bestMove[0] == byte.MaxValue || bestMove[1] == byte.MaxValue) && moves.Count > 0)
            {//All moves are valued at -inf, return one of em
                return(moves[0]);
            }
            return(bestMove);
        }
示例#5
0
        public override double EvaluateBoard(OthelloGame game, BoardStates player)
        {
            ///Based of features of the board that humans have identified.
            ///Hints of evaluation from any source I could find
            ///idealy these could me optimized using a genetic algorithm,
            ///but that is a different project


            double value = 0;
            int    empty = game.GetPieceCount(BoardStates.empty);


            if (game.GameComplete)
            {
                return(CompleteEval(player, game));
            }
            //plane funct
            //value += coinDiffSlope * (game.GetPieceCount(player) - game.GetPieceCount(~player)) + (empty * coinTimeSlope) + coinDiffOffset;
            //value += cornerDiffSlope * (game.GetCornerCount(player) - game.GetCornerCount(~player)) + (empty * cornerTimeSlope) + cornerDiffOffset;
            //value += nearCornerDiffSlope * (game.GetAdjCornerCount(player) - game.GetAdjCornerCount(~player)) + (empty * nearCornerTimeSlope) + nearCornerDiffOffset;
            //value += avalibleMoveDiffSlope * (game.GetPossiblePlayList(player).Count() - game.GetPossiblePlayList(~player).Count()) + (empty * avalibleMoveTimeSlope) + avalibleMoveDiffOffset;
            //value += nonTurnableCoinDiffSlope * (game.GetSafePeiceCountEstimation(player) - game.GetSafePeiceCountEstimation(~player)) + (empty * nonTurnableTimeSlope) + nonTurnableCoinDiffOffset;
            //value += controlledCornerDiffSlope * (game.GetControlledCorners(player) - game.GetControlledCorners(~player)) + (empty * controlledCornerTimeSlope) + controlledCornerDiffOffset;

            //power funct
            value += coinDiffSlope * Math.Pow(game.GetPieceCount(player) - game.GetPieceCount(~player) + empty - coinDiffOffset, coinTimeSlope);
            value += cornerDiffSlope * Math.Pow(game.GetCornerCount(player) - game.GetCornerCount(~player) + empty - cornerDiffOffset, cornerTimeSlope);
            value += nearCornerDiffSlope * Math.Pow(game.GetAdjCornerCount(player) - game.GetAdjCornerCount(~player) + empty - nearCornerDiffOffset, nearCornerTimeSlope);
            value += avalibleMoveDiffSlope * Math.Pow(game.GetPossiblePlayList(player).Count() - game.GetPossiblePlayList(~player).Count() + empty - avalibleMoveDiffOffset, avalibleMoveTimeSlope);
            value += nonTurnableCoinDiffSlope * Math.Pow(game.GetSafePeiceCountEstimation(player) - game.GetSafePeiceCountEstimation(~player) + empty - nonTurnableCoinDiffOffset, nonTurnableTimeSlope);
            value += controlledCornerDiffSlope * Math.Pow(game.GetControlledCorners(player) - game.GetControlledCorners(~player) + empty - controlledCornerDiffOffset, controlledCornerTimeSlope);
            return(value);
        }
示例#6
0
        public void CtorThatPiecesSetUp()
        {
            var g = new OthelloGame();

            g.board[3, 4].Should().Be(GamePiece.Black);
            g.board[3, 3].Should().Be(GamePiece.White);
            g.board[3, 2].Should().Be(GamePiece.Blank);
        }
示例#7
0
        public double Evaluate(IChromosome chromosome)
        {//Play n games vs a random (to be Neural Net), % win is Fitness
            FloatingPointChromosome myChromosome = (FloatingPointChromosome)chromosome;

            double[] genes = myChromosome.ToFloatingPoints();

            double fitness      = 0;
            double wonCount     = 0;
            object wonCountLock = new object();

            for (int index = 0; index < TEST_COUNT; index++)
            {
                //Parallel.For(0, TEST_COUNT, new ParallelOptions() { MaxDegreeOfParallelism = 2},
                //   (index) => {
                BoardStates player = (index % 2 == 0) ? BoardStates.black : BoardStates.white;

                OthelloGame      othelloGame = new OthelloGame();
                IEvaluationAgent heurAgent   = new HeuristicAgent(genes);


                while (!othelloGame.GameComplete)
                {
                    if (othelloGame.WhosTurn == player)
                    {
                        othelloGame.MakeMove(heurAgent.MakeMove(othelloGame, player));
                    }
                    else
                    {
                        othelloGame.MakeMove(opposingAgent.MakeMove(othelloGame, ~player));
                    }
                }
                if (othelloGame.GameComplete)//just gotta check
                {
                    if (othelloGame.FinalWinner == player)
                    {
                        lock (wonCountLock)
                        {
                            wonCount++;
                        }
                    }
                    else if (othelloGame.FinalWinner == BoardStates.empty)
                    {
                        lock (wonCountLock)
                        {
                            wonCount += .5;
                        }
                    }
                }
                else
                {
                    throw new Exception("EvaluationFitness didn't complete a game");
                }
                // });
            }
            fitness = (double)wonCount / TEST_COUNT;
            //System.Diagnostics.Debug.WriteLine("Fitness: " + fitness);
            return(fitness);
        }
示例#8
0
            public async Task ExecuteGroupAsync(CommandContext ctx,
                                                [Description("Move time (def. 30s).")] TimeSpan?movetime = null)
            {
                if (this.Shared.IsEventRunningInChannel(ctx.Channel.Id))
                {
                    throw new CommandFailedException("Another event is already running in the current channel!");
                }

                await this.InformAsync(ctx, StaticDiscordEmoji.Question, $"Who wants to play Othello against {ctx.User.Username}?");

                DiscordUser opponent = await ctx.WaitForGameOpponentAsync();

                if (opponent == null)
                {
                    return;
                }

                if (movetime?.TotalSeconds < 2 || movetime?.TotalSeconds > 120)
                {
                    throw new InvalidCommandUsageException("Move time must be in range of [2-120] seconds.");
                }

                var game = new OthelloGame(ctx.Client.GetInteractivity(), ctx.Channel, ctx.User, opponent, movetime);

                this.Shared.RegisterEventInChannel(game, ctx.Channel.Id);
                try {
                    await game.RunAsync();

                    if (game.Winner != null)
                    {
                        if (game.IsTimeoutReached)
                        {
                            await this.InformAsync(ctx, StaticDiscordEmoji.Trophy, $"{game.Winner.Mention} won due to no replies from opponent!");
                        }
                        else
                        {
                            await this.InformAsync(ctx, StaticDiscordEmoji.Trophy, $"The winner is: {game.Winner.Mention}!");
                        }

                        await this.Database.UpdateUserStatsAsync(game.Winner.Id, GameStatsType.OthellosWon);

                        if (game.Winner.Id == ctx.User.Id)
                        {
                            await this.Database.UpdateUserStatsAsync(opponent.Id, GameStatsType.OthellosLost);
                        }
                        else
                        {
                            await this.Database.UpdateUserStatsAsync(ctx.User.Id, GameStatsType.OthellosLost);
                        }
                    }
                    else
                    {
                        await this.InformAsync(ctx, StaticDiscordEmoji.Joystick, "A draw... Pathetic...");
                    }
                } finally {
                    this.Shared.UnregisterEventInChannel(ctx.Channel.Id);
                }
            }
示例#9
0
 public PlayAgentForm()
 {
     InitializeComponent();
     _myGame = new OthelloGame();
     InitializeAgentSelectionComboBox();
     InitializePlayerSelectionComboBox();
     InitializeMinMaxSelectionComboBox();
     SetGameCompleteVisuals(false);
 }
示例#10
0
 void Start()
 {
     OGD = othelloGameData.GetComponent <OthelloGame>();
     for (int r = 0; r < 8; r++)
     {
         for (int l = 0; l < 8; l++)
         {
             othelloBoardDataBoard[r, l] = 0;
         }
     }
 }
示例#11
0
        private static byte[] OpeningMove(BoardStates player, OthelloGame game)
        {//avoid computation for first move - only one symmetric option
         //randomly select perpendicular or diagonal for second move - parallel
         //has been shown to be much worse
         //SPECIFIC TO 8x8 BOARDS
            byte[][] firstMoves = new byte[4][] {
                new byte[] { 2, 3 },
                new byte[] { 3, 2 },
                new byte[] { 4, 5 },
                new byte[] { 5, 4 }
            };

            if (game.GetPieceCount(BoardStates.empty) == 60)
            {
                Random rndGen = new Random();
                int    rand   = (int)Math.Ceiling(rndGen.NextDouble() * 4);
                switch (rand)
                {
                case 1:
                    return(firstMoves[0]);

                case 2:
                    return(firstMoves[1]);

                case 3:
                    return(firstMoves[2]);

                case 4:
                    return(firstMoves[3]);

                default:
                    throw new Exception("OpeningMove has faulted with random number generation");
                }
            }
            if (game.GetPieceCount(BoardStates.empty) == 59)
            {
                List <byte[]> moves  = game.GetPossiblePlayList();
                Random        rndGen = new Random();
                byte          rand   = (byte)Math.Ceiling(rndGen.NextDouble() * 2);
                switch (rand)
                {
                case 1:     //diagonal
                    return(moves[0]);

                case 2:     //perpendicular
                    return(moves[0]);

                default:
                    throw new Exception("Opening move has faulted with random number generation");
                }
            }
            return(new byte[] { byte.MaxValue, byte.MaxValue });
        }
示例#12
0
 private static int CompleteEval(BoardStates player, OthelloGame game)
 {
     ///Returns complete worth of board, -inf for loss, +inf for win
     if (game.FinalWinner == player)
     {
         return(int.MaxValue);
     }
     else
     {
         return(int.MinValue);
     }
 }
示例#13
0
        public override byte[] MakeMove(OthelloGame game, BoardStates player)
        {
            List <byte[]> possibleMoves = game.GetPossiblePlayList(player);

            if (possibleMoves.Count == 0)
            {
                return new byte[] { byte.MaxValue, byte.MaxValue }
            }
            ;

            Random rndGenerator = new Random();
            int    rnd          = (int)Math.Floor(rndGenerator.NextDouble() * possibleMoves.Count);

            return(possibleMoves[rnd]);
        }
    }
示例#14
0
    // When player clicks restart. Resets the game state, hides the restart screen and removes all squares + pieces
    // to recreate them immediately after
    void buttonClicked()
    {
        Debug.Log("clicked button");
        OthelloGame.ResetState();
        restartScreen.SetActive(false);
        screenShown = false;

        GameObject baseBoard          = GameObject.Find("Game_board");
        Transform  baseboardTransform = baseBoard.GetComponent <Transform>();
        var        children           = new List <GameObject>();

        foreach (Transform child in baseboardTransform)
        {
            children.Add(child.gameObject);
        }
        children.ForEach(child => Destroy(child));
        baseBoard.GetComponent <CreateSquares>().InitSquares();
    }
            public async Task ExecuteGroupAsync(CommandContext ctx,
                                                [Description("desc-game-movetime")] TimeSpan?moveTime = null)
            {
                if (moveTime?.TotalSeconds is < 2 or > 120)
                {
                    throw new InvalidCommandUsageException(ctx, "cmd-err-game-movetime", 2, 120);
                }

                if (this.Service.IsEventRunningInChannel(ctx.Channel.Id))
                {
                    throw new CommandFailedException(ctx, "cmd-err-evt-dup");
                }

                DiscordUser?opponent = await ctx.WaitForGameOpponentAsync();

                if (opponent is null)
                {
                    throw new CommandFailedException(ctx, "cmd-err-game-op-none", ctx.User.Mention);
                }

                var game = new OthelloGame(ctx.Client.GetInteractivity(), ctx.Channel, ctx.User, opponent, moveTime);

                this.Service.RegisterEventInChannel(game, ctx.Channel.Id);
                try {
                    await game.RunAsync(this.Localization);

                    if (game.Winner is { })
                    {
                        if (game.IsTimeoutReached)
                        {
                            await ctx.ImpInfoAsync(this.ModuleColor, Emojis.Trophy, "str-game-timeout", game.Winner.Mention);
                        }
                        else
                        {
                            await ctx.ImpInfoAsync(this.ModuleColor, Emojis.Trophy, "fmt-winners", game.Winner.Mention);
                        }

                        GameStatsService gss = ctx.Services.GetRequiredService <GameStatsService>();
                        await gss.UpdateStatsAsync(game.Winner.Id, s => s.OthelloWon++);

                        await gss.UpdateStatsAsync(game.Winner == ctx.User?opponent.Id : ctx.User.Id, s => s.OthelloLost++);
                    }
示例#16
0
        public override byte[] MakeMove(OthelloGame game, BoardStates player)
        {
            List <byte[]> moves = game.GetPossiblePlayList(player);

            double bestScore = double.MinValue;

            byte[] bestMove = new byte[] { byte.MaxValue, byte.MaxValue };

            foreach (byte[] move in moves)
            {
                OthelloGame testGame = game.DeepCopy();
                testGame.MakeMove(move);

                double thisScore = EvaluateBoard(testGame, player);

                if (thisScore > bestScore)
                {
                    bestScore = thisScore;
                    bestMove  = move;
                }
            }
            return(bestMove);
        }
示例#17
0
 public override double EvaluateBoard(OthelloGame game, BoardStates player)
 {
     return(game.GetPieceCount(player));
 }
示例#18
0
        public void MoveWhenOccupiedShouldReturnFalse()
        {
            var g = new OthelloGame();

            g.Move(3, 3).Should().BeFalse();
        }
示例#19
0
        public void MoveWhenNotOccupiedShouldReturnTrue()
        {
            var g = new OthelloGame();

            g.Move(3, 5).Should().BeTrue();
        }
示例#20
0
    // Detects touch input and also detects if this square object has been pressed. If yes, then adds the piece to the board
    // If piece is already on board but needs to change color, it is destroyed then recreated on the opposite side.
    // (THIS PART NEED TO BE ADJUSTED BOTH FOR ANIMATION AND CROSSHAIR STYLE OF PLAY)
    void Update()
    {
        List <string> validMoves = OthelloGame.validMoves;

        string[] square_num = gameObject.name.Split('_');
        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)  // If touch is detected by user

        {
            Ray        ray    = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
            RaycastHit rayhit = new RaycastHit();
            if (Physics.Raycast(ray, out rayhit))                                                              // If touch by user hit the square object
            {
                string hitObjectName = rayhit.transform.name;                                                  // Get the name of the square object hit
                if (placed == false && hitObjectName == gameObject.name && validMoves.Contains(square_num[1])) // If this square, no piece placed there and move on square is valid
                {
                    GameObject hitObject          = GameObject.Find(gameObject.name);                          // Almost same code below as Start()
                    Transform  hitObjectTransform = hitObject.GetComponent <Transform>();
                    if (OthelloGame.currentTurn == "black")
                    {
                        GameObject piece = Instantiate(pieceObj, hitObjectTransform);
                        piece.transform.localRotation = Quaternion.Euler(0f, 0f, 180f);
                        piece.transform.localPosition = new Vector3(piece.transform.localPosition.x, 4, piece.transform.localPosition.z);
                        piece.name = "piece_" + square_num[1];
                        placed     = true;

                        OthelloGame.PlacePiece(square_num[1]);                              // Place piece in the board state (backend code)
                    }
                    else
                    {
                        GameObject piece = Instantiate(pieceObj, hitObjectTransform);
                        piece.name = "piece_" + square_num[1];
                        placed     = true;
                        OthelloGame.PlacePiece(square_num[1]);
                    }
                }
            }
        }
        if (placed == true && OthelloGame.piecesToConvert.Contains(square_num[1]))          // If player has won this piece from opponent, convert it
        {
            StartCoroutine(sound());                                                        // The sound starts as soon as every piece converts
            Vibration.Vibrate(OthelloGame.piecesToConvertLength * 50);                      // the vibrate starts as as soon as every piece converts
            var children = new List <GameObject>();
            foreach (Transform child in transform)
            {
                children.Add(child.gameObject);                                             // Add all children of square object to a temporary list
            }
            //children.ForEach(child => Destroy(child));                                      // Destroy piece to create new (if animation later, shouldn't destroy)
            if (OthelloGame.currentTurn == "white")
            {
                children.ForEach(child => child.GetComponent <PieceAnimate>().PieceFlipWtoB());
            }
            if (OthelloGame.currentTurn == "black")
            {
                children.ForEach(child => child.GetComponent <PieceAnimate>().PieceFlipBtoW());
            }



            OthelloGame.ApplyConvertOfPiece(square_num[1]);                                 // Remove piece from state so the view only update once with the new one

            /*
             * GameObject squareObject = GameObject.Find(gameObject.name);
             * Transform squareObjectTransform = squareObject.GetComponent<Transform>();
             *
             * if (OthelloGame.currentTurn == "white")
             * {
             *  GameObject piece = Instantiate(pieceObj, squareObjectTransform);
             *  piece.transform.localRotation = Quaternion.Euler(0f, 0f, 180f);
             *  piece.transform.localPosition = new Vector3(piece.transform.localPosition.x, 4, piece.transform.localPosition.z);
             *  piece.GetComponent<PieceAnimate>().PieceDropWhite(); // init drop piece animation
             *  piece.name = "piece_" + square_num[1];
             *  placed = true;
             *
             * }
             * else if (OthelloGame.currentTurn == "black")
             * {
             *  GameObject piece = Instantiate(pieceObj, squareObjectTransform);
             *
             *  piece.name = "piece_" + square_num[1];
             *  piece.GetComponent<PieceAnimate>().PieceDropBlack(); // init drop piece animation
             * }
             */
        }
    }
示例#21
0
 void Start()
 {
     board   = transform.parent.GetComponent <OthelloGame>();
     cell    = transform.Find("Disk").GetComponent <Image>();
     isBlack = false;
 }
示例#22
0
 public Computer(OthelloGame.eGameToken i_Token, OthelloGame i_Game)
 {
     r_ComputerToken = i_Token;
     m_TheGame       = i_Game;
     m_MinimaxTree   = new Minimax(m_TheGame.GameBoardSize);
 }
示例#23
0
 public abstract double EvaluateBoard(OthelloGame game, BoardStates player);