private void ConfigureComputer() { game.RegisterEngine(Player.One, engines.GetEngine(cbPlayerOne.Text)); game.RegisterEngine(Player.Two, engines.GetEngine(cbPlayerTwo.Text)); game.ComputerPlay(); }
public void Draw(VolcanoGame game, Point mouseLocation, int moveNumber, bool highlightLastMove, bool displayHeatmap) { Resize(); if (GraphicsSettings.IdealPanelWidth <= 100 || GraphicsSettings.IdealPanelHeight <= 20) { using (Graphics g3 = _panel.CreateGraphics()) { g3.Clear(SystemColors.ControlDark); g3.DrawString(":)", new Font("Tahoma", 8f * _fontScale, FontStyle.Regular), Brushes.White, new Point(1, 1)); } return; } bool reviewMode = game.MoveHistory.Count > 0 && moveNumber != game.MoveHistory.Count; int hoverTile = GetTileIndex(mouseLocation); Board gameState = reviewMode ? game.GetPreviousState(moveNumber) : game.CurrentState; Point mouse = GetOffsetPoint(mouseLocation); int lastPlayIndex = GetTileIndexFromBoardIndex(game.MoveHistory.Count >= moveNumber && moveNumber - 1 >= 0 ? game.MoveHistory[moveNumber - 1] : -1); Color background = reviewMode ? GraphicsSettings.ReviewBackgroundColor : GraphicsSettings.BackgroundColor; if (displayHeatmap) { if (gameState.Turn != analysisMove) { EndAnalysis(); analysisMove = gameState.Turn; analysisEngine = new VolcanoGame(); analysisEngine.SecondsPerEngineMove = 1000000; analysisEngine.RegisterEngine(Player.One, new MonteCarloTreeSearchEngine(false, true, true, "")); analysisEngine.RegisterEngine(Player.Two, new MonteCarloTreeSearchEngine(false, true, true, "")); analysisEngine.OnEngineStatus += AnalysisEngine_OnEngineStatus; analysisEngine.CurrentState = new Board(gameState); analysisEngine.ComputerPlay(); } } else { EndAnalysis(); } using (Bitmap b = new Bitmap(GraphicsSettings.IdealPanelWidth, GraphicsSettings.IdealPanelHeight)) using (Graphics g = Graphics.FromImage(b)) { g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.Clear(background); // Draw equator if (GraphicsSettings.ShowEquator) { var allPoints = new List <PointF>(); for (int i = 0; i < 80; i++) { // If this is a northern tile if (Constants.TileNames[boardIndexFromTileIndex[i]].Contains("N")) { foreach (int adjacent in Constants.AdjacentIndexes[i]) { // If this northern tile has an adjacent southern tile if (Constants.TileNames[boardIndexFromTileIndex[adjacent]].Contains("S")) { var rect = _tiles[adjacent].Path.GetBounds(); var center = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); // Find two points closest to the adjacent tile var points = _tiles[i].Path.PathPoints.OrderBy(x => Math.Sqrt(Math.Pow(x.X - center.X, 2) + Math.Pow(x.Y - center.Y, 2))).ToList(); var pointsAdjacent = _tiles[adjacent].Path.PathPoints.OrderBy(x => Math.Sqrt(Math.Pow(x.X - points[0].X, 2) + Math.Pow(x.Y - points[0].Y, 2))).ToList(); // Average them to get a line exactly halfway between the two tiles var centerOne = new PointF((points[0].X + pointsAdjacent[0].X) / 2, (points[0].Y + pointsAdjacent[0].Y) / 2); var centerTwo = new PointF((points[1].X + pointsAdjacent[1].X) / 2, (points[1].Y + pointsAdjacent[1].Y) / 2); // Save the points so we can draw them all at once later allPoints.Add(centerOne); allPoints.Add(centerTwo); } } } } // Sort the points left to right so we don't have a line jumping randomly all of the board allPoints.Sort((c, n) => c.X.CompareTo(n.X)); var pen = new Pen(GraphicsSettings.EquatorColor, GraphicsSettings.TileSpacing * 0.75f); pen.EndCap = LineCap.Round; pen.StartCap = LineCap.Round; g.DrawLines(pen, allPoints.ToArray()); //var width = GraphicsSettings.TileSpacing; //for (int t = width; t >= 1; t--) //{ // var color = Color.FromArgb(255 - 255 * t / width, GraphicsSettings.EquatorColor.R, GraphicsSettings.EquatorColor.G, GraphicsSettings.EquatorColor.B); // var pen = new Pen(color, t); // pen.EndCap = LineCap.Round; // pen.StartCap = LineCap.Round; // g.DrawLines(pen, allPoints.ToArray()); //} } // Draw rotation buttons if (GraphicsSettings.ShowRotationButtons) { for (int i = 0; i < _rotations.Count; i++) { float opacity = 0.25f; if (_rotations[i].IsWithinCircle(mouse)) { opacity = 1f; } ColorMatrix matrix = new ColorMatrix(); matrix.Matrix33 = opacity; ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(_rotations[i].Image, _rotations[i].BoundingBoxFull, 0, 0, _rotations[i].Image.Width, _rotations[i].Image.Height, GraphicsUnit.Pixel, attributes); } } // Draw tiles for (int i = 0; i < 80; i++) { DrawTile(g, gameState, i, hoverTile, lastPlayIndex, highlightLastMove); if (displayHeatmap) { var details = analysisStatus?.Details?.FirstOrDefault(x => x.MoveIndex == boardIndexFromTileIndex[i]); if (details != null) { var min = analysisStatus.Details.Min(x => x.Evaluation); var max = analysisStatus.Details.Max(x => x.Evaluation); var scale = 1.0; if (max - min > 0) { scale = (details.Evaluation - min) / (max - min); } var isBest = details.Evaluation == max; FillRoundedRectangle(g, i, scale, isBest); DrawTileText(g, i, details.Evaluation.ToString(), 3, GraphicsSettings.SubTextFontSize, false, Color.Black); } } else if (GraphicsSettings.ShowTileNames) { DrawTileSubText(g, i, Constants.TileNames[boardIndexFromTileIndex[i]]); } if (gameState.Tiles[boardIndexFromTileIndex[i]] == 0) { if (GraphicsSettings.ShowTileIndexes) { DrawTileMainText(g, i, boardIndexFromTileIndex[i].ToString()); } //DrawTileMainText(g, i, Constants.FastestPaths[i].Length.ToString()); } else { int value = Math.Abs(gameState.Tiles[boardIndexFromTileIndex[i]]); if (!GraphicsSettings.ShowTileNames) { if (Math.Abs(gameState.Tiles[boardIndexFromTileIndex[i]]) <= VolcanoGame.Settings.MaxMagmaChamberLevel) { DrawTileSubText(g, i, "Chamber"); } else { value -= VolcanoGame.Settings.MaxMagmaChamberLevel; DrawTileSubText(g, i, "Volcano"); } } DrawTileMainText(g, i, value.ToString()); } } // Draw turn clock if (_clock.Width > 0) { var lastToMove = moveNumber % 6; var centerCover = new RectangleF(_clock.X + _clock.Width / 3, _clock.Y + _clock.Width / 3, _clock.Width / 3, _clock.Width / 3); var angle = 360f / 6; var start = -90f - angle / 2; var moveColor = GraphicsSettings.EmptyTileColor; switch (lastToMove) { case 0: case 4: moveColor = GraphicsSettings.PlayerOneVolcanoTileColor; break; case 1: case 3: moveColor = GraphicsSettings.PlayerTwoVolcanoTileColor; break; } var shadeColor = Color.FromArgb(128, 255, 255, 255); var player1brush = new SolidBrush(GraphicsSettings.PlayerOneVolcanoTileColor); var player2brush = new SolidBrush(GraphicsSettings.PlayerTwoVolcanoTileColor); var growthBrush = new SolidBrush(GraphicsSettings.EmptyTileColor); var playerToMoveBrush = new SolidBrush(moveColor); var playerToMovePen = new Pen(moveColor, 8f * _fontScale); var shadeBrush = new SolidBrush(shadeColor); g.FillPie(player1brush, _clock, start, angle); g.FillPie(player2brush, _clock, start + angle, angle); g.FillPie(growthBrush, _clock, start + angle * 2, angle); g.FillPie(player2brush, _clock, start + angle * 3, angle); g.FillPie(player1brush, _clock, start + angle * 4, angle); g.FillPie(growthBrush, _clock, start + angle * 5, angle); g.FillPie(shadeBrush, _clock, start + angle * lastToMove + angle, angle * 5); g.DrawPie(playerToMovePen, _clock, start + angle * lastToMove, angle); g.FillEllipse(playerToMoveBrush, centerCover); } using (Bitmap b2 = new Bitmap(_panel.Width, _panel.Height)) using (Graphics g2 = Graphics.FromImage(b2)) using (Graphics g3 = _panel.CreateGraphics()) { g2.Clear(background); g2.DrawImage(b, (_panel.Width - GraphicsSettings.IdealPanelWidth) / 2, (_panel.Height - GraphicsSettings.IdealPanelHeight) / 2, GraphicsSettings.IdealPanelWidth, GraphicsSettings.IdealPanelHeight); Color playerColor = gameState.Player == Player.One ? GraphicsSettings.PlayerOneVolcanoTileColor : GraphicsSettings.PlayerTwoVolcanoTileColor; g2.DrawString("Turn " + gameState.Turn, new Font("Tahoma", 12f * _fontScale, FontStyle.Bold), new SolidBrush(playerColor), new Point(5, 5)); if (gameState.State == GameState.GameOver) { playerColor = gameState.Winner == Player.One ? GraphicsSettings.PlayerOneVolcanoTileColor : GraphicsSettings.PlayerTwoVolcanoTileColor; string gameOver = "Game Over!"; Font f = new Font("Tahoma", 12f * _fontScale, FontStyle.Bold); SizeF size = g.MeasureString(gameOver, f); g2.DrawString(gameOver, f, new SolidBrush(playerColor), new Point(_panel.Width - (int)size.Width - 5, 5)); } g2.DrawString(game.NodesPerSecond.ToString() + " NPS", new Font("Tahoma", 12f, FontStyle.Bold), Brushes.Gray, new Point(5, _panel.Height - 25)); // Double buffering g3.DrawImage(b2, 0, 0, _panel.Width, _panel.Height); } } }