private void MakeArtificialMouseHoverLine(string first, string second) { LineBetweenCircles line = new LineBetweenCircles(); int tmp1, tmp2; if (Int32.TryParse(first, out tmp1)) // horizontal line { tmp2 = Miscellaneous.TranslateLetterToAxis(second[0]); line.CoordinateFrom = new VTuple <int, int>(tmp1, tmp2); line.CoordinateTo = new VTuple <int, int>(tmp1, tmp2 + 1); } else // vertical line { tmp1 = Miscellaneous.TranslateLetterToAxis(first[0]); tmp2 = Int32.Parse(second); line.CoordinateFrom = new VTuple <int, int>(tmp1, tmp2); line.CoordinateTo = new VTuple <int, int>(tmp1 + 1, tmp2); } line.From = (Point)circleCenters[line.CoordinateFrom]; line.To = (Point)circleCenters[line.CoordinateTo]; line.WhoDrew = currentGame.Turn; FinishTurn(line); }
private void MinimaxTree_AfterSelect(object sender, TreeViewEventArgs e) { if (e.Node != null) { ModifiedTreeNode node = (ModifiedTreeNode)e.Node; selectedNode = node.MinimaxTreeNode; deltaLine = selectedNode.DeltaMove; canvas.Refresh(); } }
private bool TransferFromNonExistingToExisting(LineBetweenCircles line) { for (int i = 0; i < nonExistingLines.Count; i++) { if ((nonExistingLines[i].CoordinateFrom == line.CoordinateFrom && nonExistingLines[i].CoordinateTo == line.CoordinateTo) || (nonExistingLines[i].CoordinateTo == line.CoordinateFrom && nonExistingLines[i].CoordinateFrom == line.CoordinateTo)) { LineBetweenCircles trueLine = nonExistingLines[i]; nonExistingLines.RemoveAt(i); existingCanvasLines.Add(trueLine); return(true); } } return(false); }
private void Canvas_MouseClick(object sender, MouseEventArgs e) { if (currentGame == null) { MessageBox.Show("Igra nije započeta!"); return; } else if (currentGame.Opponent != null && currentGame.Opponent2 != null) { return; } if (mouseHoverLine != null && !currentGame.GameOver) { FinishTurn(mouseHoverLine); mouseHoverLine = null; // refreshing done inside FinishTurn(...) } }
private void CreateNonExistingMovesList() { nonExistingLines.Clear(); // horizontal lines for (int i = 0; i < currentGame.TableSizeX; i++) // rows { for (int j = 0; j < currentGame.TableSizeY - 1; j++) // columns { LineBetweenCircles newLine = new LineBetweenCircles(); newLine.CoordinateFrom = new VTuple <int, int>(i, j); newLine.CoordinateTo = new VTuple <int, int>(i, j + 1); newLine.From = (Point)circleCenters[newLine.CoordinateFrom]; newLine.To = (Point)circleCenters[newLine.CoordinateTo]; nonExistingLines.Add(newLine); } } // vertical lines for (int j = 0; j < currentGame.TableSizeY; j++) // rows { for (int i = 0; i < currentGame.TableSizeX - 1; i++) // columns { LineBetweenCircles newLine = new LineBetweenCircles(); newLine.CoordinateFrom = new VTuple <int, int>(i, j); newLine.CoordinateTo = new VTuple <int, int>(i + 1, j); newLine.From = (Point)circleCenters[newLine.CoordinateFrom]; newLine.To = (Point)circleCenters[newLine.CoordinateTo]; nonExistingLines.Add(newLine); } } Miscellaneous.ShuffleList(nonExistingLines); }
public static List <Box> TryClosingBoxes(List <LineBetweenCircles> existingCanvasLines, Player player, LineBetweenCircles line, out int[] surroundingEdges) { List <Box> result = new List <Box>(); surroundingEdges = new int[2]; surroundingEdges[0] = surroundingEdges[1] = 0; int coordinateFromX = line.CoordinateFrom.Item1; int coordinateFromY = line.CoordinateFrom.Item2; int coordinateToX = line.CoordinateTo.Item1; int coordinateToY = line.CoordinateTo.Item2; if (coordinateFromX == coordinateToX) { // horizontal line for (int direction = 0; direction < 2; direction++) { // DIRECTION(0) -> ABOVE // DIRECTION(1) -> BELOW // (line where x = 0 doesn't have upper element if (coordinateFromX == 0 && direction == 0) { continue; } int dx = (direction == 0 ? -1 : 1); // check for clojure both above and below the line Box box = new Box(); bool upperLeft = false; bool upperUpper = false; bool upperRight = false; for (int i = 0; i < existingCanvasLines.Count; i++) { // looking for left and right if (coordinateFromY < coordinateToY) { if (direction == 0) { box.BottomLeft = line.From; box.BottomRight = line.To; } else { box.TopLeft = line.From; box.TopRight = line.To; } // 'from' is left edge if (!upperLeft && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)))) { upperLeft = true; box.LeftEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } // 'to' is right edge if (!upperRight && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX + dx, coordinateToY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX + dx, coordinateToY)))) { upperRight = true; box.RightEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!upperUpper && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY + 1)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY + 1)))) { upperUpper = true; if (direction == 0) { box.UpperEdge = existingCanvasLines[i]; } else { box.BottomEdge = existingCanvasLines[i]; } surroundingEdges[direction]++; continue; } } else { if (direction == 0) { box.BottomLeft = line.To; box.BottomRight = line.From; } else { box.TopLeft = line.To; box.TopRight = line.From; } // 'from' is right edge if (!upperRight && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)))) { upperRight = true; box.RightEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } // 'to' is left edge if (!upperLeft && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX + dx, coordinateToY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX + dx, coordinateToY)))) { upperLeft = true; box.LeftEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!upperUpper && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX + dx, coordinateToY) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX + dx, coordinateToY) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX + dx, coordinateFromY)))) { upperUpper = true; if (direction == 0) { box.UpperEdge = existingCanvasLines[i]; } else { box.BottomEdge = existingCanvasLines[i]; } surroundingEdges[direction]++; continue; } } if (upperLeft && upperUpper && upperRight) { break; } } // add to list of boxes if (upperLeft && upperUpper && upperRight) { box.ClosingPlayer = player; if (direction == 0) { box.BottomEdge = line; box.TopLeft = (box.UpperEdge.From.X < box.UpperEdge.To.X ? box.UpperEdge.From : box.UpperEdge.To); box.TopRight = (box.UpperEdge.From.X > box.UpperEdge.To.X ? box.UpperEdge.From : box.UpperEdge.To); } else { box.UpperEdge = line; box.BottomLeft = (box.BottomEdge.From.X < box.BottomEdge.To.X ? box.BottomEdge.From : box.BottomEdge.To); box.BottomRight = (box.BottomEdge.From.X > box.BottomEdge.To.X ? box.BottomEdge.From : box.BottomEdge.To); } result.Add(box); } } } else if (coordinateFromY == coordinateToY) { // vectical line for (int direction = 0; direction < 2; direction++) { // DIRECTION(0) -> LEFT // DIRECTION(1) -> RIGHT if (coordinateFromY == 0 && direction == 0) { continue; } int dy = (direction == 0 ? -1 : 1); Box box = new Box(); bool upper = false; bool left = false; bool bottom = false; for (int i = 0; i < existingCanvasLines.Count; i++) { if (coordinateFromX < coordinateToX) { if (direction == 0) { box.TopRight = line.From; box.BottomRight = line.To; } else { box.TopLeft = line.From; box.BottomLeft = line.To; } // 'from' is up // 'to' is down if (!bottom && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY)))) { bottom = true; box.BottomEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!upper && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY)))) { upper = true; box.UpperEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!left && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy)))) { left = true; if (direction == 0) { box.LeftEdge = existingCanvasLines[i]; } else { box.RightEdge = existingCanvasLines[i]; } surroundingEdges[direction]++; continue; } } else { if (direction == 0) { box.TopRight = line.To; box.BottomRight = line.From; } else { box.TopLeft = line.To; box.BottomLeft = line.From; } // 'from' is down // 'to' is up if (!bottom && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY)))) { bottom = true; box.BottomEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!upper && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY)))) { upper = true; box.UpperEdge = existingCanvasLines[i]; surroundingEdges[direction]++; continue; } if (!left && ((existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateToX, coordinateToY + dy)) || (existingCanvasLines[i].CoordinateTo == new VTuple <int, int>(coordinateFromX, coordinateFromY + dy) && existingCanvasLines[i].CoordinateFrom == new VTuple <int, int>(coordinateToX, coordinateToY + dy)))) { left = true; if (direction == 0) { box.LeftEdge = existingCanvasLines[i]; } else { box.RightEdge = existingCanvasLines[i]; } surroundingEdges[direction]++; continue; } } } if (upper && left && bottom) { box.ClosingPlayer = player; if (direction == 0) { box.RightEdge = line; box.TopLeft = (box.UpperEdge.From.X < box.UpperEdge.To.X ? box.UpperEdge.From : box.UpperEdge.To); box.BottomLeft = (box.BottomEdge.From.X < box.BottomEdge.To.X ? box.BottomEdge.From : box.BottomEdge.To); } else { box.LeftEdge = line; box.TopRight = (box.UpperEdge.From.X > box.UpperEdge.To.X ? box.UpperEdge.From : box.UpperEdge.To); box.BottomRight = (box.BottomEdge.From.X > box.BottomEdge.To.X ? box.BottomEdge.From : box.BottomEdge.To); } result.Add(box); } } } else { throw new Exception("Diagonal connections now allowed."); } return(result); }
private void FinishTurn(LineBetweenCircles line) { if (line == null) { throw new Exception("AI returned null for the next move."); } // will return false if clicked on line that had already been drawn on the canvas if (!TransferFromNonExistingToExisting(line)) { return; } /////////////////////////////////// string log = line.ToString(); int startPosition = turnRichTextBox.Text.Length; string textToAppend = log + Environment.NewLine; turnRichTextBox.AppendText(textToAppend); turnRichTextBox.SelectionStart = startPosition; turnRichTextBox.SelectionLength = log.Length; turnRichTextBox.SelectionColor = (currentGame.Turn == Player.BLUE ? Color.Blue : Color.Red); turnRichTextBox.ScrollToCaret(); /////////////////////////////////// List <Box> newBoxes = AICommon.TryClosingBoxes(existingCanvasLines, currentGame.Turn, line, out int[] notUsed); boxes.AddRange(newBoxes); currentGame.Score[(int)currentGame.Turn] += newBoxes.Count; if (newBoxes.Count > 0) { canvas.Refresh(); UpdateGUI(); } if (boxes.Count == (currentGame.TableSizeX - 1) * (currentGame.TableSizeY - 1)) { currentGame.GameOver = true; } if (currentGame.GameOver) { UpdateGUI(); GUI_GameSettingChanged(null, null); MessageBox.Show("Igra je završena"); } else if (currentGame.Opponent2 == null) // pc vs pc will be handled in other method -> PcNextStep { if (currentGame.Turn == Player.BLUE) { if (newBoxes.Count == 0) { SwitchTurn(); if (currentGame.Opponent != null) { FinishTurn(currentGame.Opponent.MakeTurn()); } } UpdateGUI(); } else { if (newBoxes.Count == 0) { SwitchTurn(); } else if (newBoxes.Count > 0 && currentGame.Opponent != null) { UpdateGUI(); Thread.Sleep(1000); FinishTurn(currentGame.Opponent.MakeTurn()); } UpdateGUI(); } } else if (currentGame.Opponent != null && currentGame.Opponent2 != null) { if (newBoxes.Count == 0) { SwitchTurn(); } UpdateGUI(); canvas.Refresh(); } }
private void NewGame_Click(object sender, EventArgs e) { BasePlayer opponent = null; BasePlayer opponent2 = null; pcNextStep.Enabled = false; if (humanVsHumanRadio.Checked) { opponent = null; } else if (humanVsPcRadio.Checked) { opponent = CreateOpponent(aiDifficulty.SelectedIndex, Player.RED); if (opponent == null) { return; } } else { opponent = CreateOpponent(aiDifficulty.SelectedIndex, Player.BLUE); opponent2 = CreateOpponent(aiDifficulty.SelectedIndex, Player.RED); if (opponent == null || opponent2 == null) { return; } pcNextStep.Enabled = true; } // creating new game currentGame = new CurrentGame((int)tableSizeX.Value, (int)tableSizeY.Value, opponent, opponent2); // this cannot be moved to constructor of current game because object reference can be // retrieved once the constructor has finished if (currentGame.Opponent != null) { currentGame.Opponent.SetCurrentGame(currentGame); } if (currentGame.Opponent2 != null) { currentGame.Opponent2.SetCurrentGame(currentGame); } Logic.CalculateCanvasParameters(currentGame.TableSizeX, currentGame.TableSizeY, canvas.Width, canvas.Height, out horizontalSpacingBetweenCircles, out verticalSpacingBetweenCircles, out circleDiameter); // clearing existing data structures mouseHoverLine = null; existingCanvasLines.Clear(); boxes.Clear(); circleCenters.Clear(); turnRichTextBox.Clear(); UpdateGUI(); canvas.Refresh(); CreateNonExistingMovesList(); }
private void Canvas_MouseMove(object sender, MouseEventArgs e) { // finding the closes circle object min = null; foreach (DictionaryEntry pair in circleCenters) { Point p = (Point)pair.Value; if (min == null) { min = pair; } else if ((Math.Abs(e.X - p.X) <= (horizontalSpacingBetweenCircles + circleDiameter) / 2) && (Math.Abs(e.Y - p.Y) <= (verticalSpacingBetweenCircles + circleDiameter) / 2)) { min = pair; } else { continue; } } if (min != null) { // closest circle found Point minPoint = (Point)(((DictionaryEntry)min).Value); Point?coordinateTo = null; // if in designated line area if ((Math.Abs(e.X - minPoint.X) <= (horizontalSpacingBetweenCircles + circleDiameter) / 2) && (Math.Abs(e.Y - minPoint.Y) <= (verticalSpacingBetweenCircles + circleDiameter) / 2)) { VTuple <int, int> coordinatesFrom = (VTuple <int, int>)((DictionaryEntry)min).Key; //Debug.WriteLine("min coordinates (" + coordinatesFrom.Item1 + ", " + coordinatesFrom.Item2 + ")"); int dx = 0, dy = 0; bool valid = false; if ((e.Y >= (minPoint.Y - verticalSpacingBetweenCircles / 2 - circleDiameter / 2)) && (e.Y <= minPoint.Y - circleDiameter / 2) && (Math.Abs(e.X - minPoint.X) <= LINE_WIDTH)) { // up if (coordinatesFrom.Item1 != 0) { valid = true; dx = -1; } } else if ((e.Y >= minPoint.Y + circleDiameter / 2) && (e.Y <= (minPoint.Y + verticalSpacingBetweenCircles / 2 + circleDiameter / 2)) && (Math.Abs(e.X - minPoint.X) <= LINE_WIDTH)) { // down if (coordinatesFrom.Item1 != currentGame.TableSizeX - 1) { valid = true; dx = 1; } } else if ((e.X >= (minPoint.X - horizontalSpacingBetweenCircles / 2 - circleDiameter / 2)) && (e.X <= minPoint.X - circleDiameter / 2) && (Math.Abs(e.Y - minPoint.Y) <= LINE_WIDTH)) { // left if (coordinatesFrom.Item2 != 0) { valid = true; dy = -1; } } else if ((e.X >= minPoint.X + circleDiameter / 2) && (e.X <= (minPoint.X + horizontalSpacingBetweenCircles / 2 + circleDiameter / 2)) && (Math.Abs(e.Y - minPoint.Y) <= LINE_WIDTH)) { // right if (coordinatesFrom.Item2 != currentGame.TableSizeY - 1) { valid = true; dy = 1; } } else { valid = false; } // signal drawing of temporary line if (valid) { VTuple <int, int> lookingFor = new VTuple <int, int>(coordinatesFrom.Item1 + dx, coordinatesFrom.Item2 + dy); //Debug.WriteLine("Looking for (" + (coordinatesFrom.Item1 + dx) + ", " + (coordinatesFrom.Item2 + dy) + ")"); if (circleCenters[lookingFor] != null) { coordinateTo = (Point)circleCenters[lookingFor]; LineBetweenCircles line = new LineBetweenCircles(); line.From = minPoint; line.To = (Point)coordinateTo; line.CoordinateFrom = coordinatesFrom; line.CoordinateTo = lookingFor; line.WhoDrew = currentGame.Turn; if (mouseHoverLine != null && mouseHoverLine.From == line.From && mouseHoverLine.To == line.To) { return; } else { mouseHoverLine = line; canvas.Refresh(); } } } else { // clear non-existing hover line because user has exited the area if (mouseHoverLine != null) { mouseHoverLine = null; canvas.Refresh(); } } } } }