Advertisement
Guest User

Russian Draughts

a guest
Jun 6th, 2020
546
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 26.46 KB | None | 0 0
  1. import java.util.LinkedList;
  2.  
  3. final int BoardSize = 8; // размер доски в квадратах
  4. final float SquareSize = 50; // размер квадрата в пикселях
  5. final float PieceSize = 0.6 * SquareSize; // диаметр шашки
  6. final color BgColor = color(100); // цвет фона
  7.  
  8. PlayerT whitePlayerT = PlayerT.Person;
  9. PlayerT blackPlayerT = PlayerT.Bot;
  10.  
  11. // Загрузить расстановку шашек из редактора или расставить стандартно
  12. boolean loadGameFromEditor = false;
  13.  
  14. Menu menu;
  15. Game game;
  16. Editor editor;
  17. Scene currentScene;
  18.  
  19. enum PlayerT {
  20.   Person,
  21.   Bot
  22. }
  23.  
  24. static class Vec2Int {
  25.   final int x;
  26.   final int y;
  27.  
  28.   Vec2Int(int x, int y) {
  29.     this.x = x;
  30.     this.y = y;
  31.   }
  32.  
  33.   Vec2Int add(Vec2Int v) {
  34.     return new Vec2Int(x + v.x, y + v.y);
  35.   }
  36.  
  37.   boolean equals(Vec2Int v) {
  38.     return x == v.x && y == v.y;
  39.   }
  40. }
  41.  
  42. enum Dir {
  43.   DownRight(1, 1), DownLeft(-1, 1), UpLeft(-1, -1), UpRight(1, -1);
  44.  
  45.   final Vec2Int vec;
  46.  
  47.   private Dir(int x, int y) {
  48.     vec = new Vec2Int(x, y);
  49.   }
  50.  
  51.   Dir left() {
  52.     Dir[] vals = values();
  53.     int i = ordinal() - 1;
  54.     if (i < 0) i += vals.length;
  55.     return vals[i];
  56.   }
  57.  
  58.   Dir right() {
  59.     Dir[] vals = values();
  60.     return vals[(ordinal() + 1) % vals.length];
  61.   }
  62.  
  63.   Dir[] perpendiculars() {
  64.     return new Dir[] {left(), right()};
  65.   }
  66. }
  67.  
  68. Dir[] forwardDirs(Color c) {
  69.   if (c == Color.White) {
  70.     return new Dir[] {Dir.UpLeft, Dir.UpRight};
  71.   } else {
  72.     return new Dir[] {Dir.DownRight, Dir.DownLeft};
  73.   }
  74. }
  75.  
  76. Dir[] backwardDirs(Color c) {
  77.   return forwardDirs(c.getInverse());
  78. }
  79.  
  80. enum Color {
  81.   White {
  82.     Color getInverse() {
  83.       return Black;
  84.     }
  85.   },
  86.   Black {
  87.     Color getInverse() {
  88.       return White;
  89.     }
  90.   };
  91.  
  92.   abstract Color getInverse();
  93. }
  94.  
  95. int lastRow(Color col) {
  96.   if (col == Color.White) return 0;
  97.   return BoardSize - 1;
  98. }
  99.  
  100. // хранит информацию о ходе
  101. // направление движения
  102. // квадрат, в который встает шашка
  103. // ссылка на шашку, которая бьется в этом ходу
  104. class Move {
  105.   final Dir direction;
  106.   final Vec2Int position;
  107.   final Piece capturedPiece;
  108.  
  109.   Move(Dir dir, Vec2Int pos, Piece piece) {
  110.     direction = dir;
  111.     position = pos;
  112.     capturedPiece = piece;
  113.   }
  114.  
  115.   Move(Dir dir, Vec2Int pos) {
  116.     this(dir, pos, null);
  117.   }
  118. }
  119.  
  120. class Piece {
  121.   Vec2Int position;
  122.   Color col;
  123.   boolean king = false; // дамка
  124.   boolean captured = false; // битая
  125.   ArrayList<Move> moves = new ArrayList<Move>(); // ходы без взятия
  126.   ArrayList<Move> captures = new ArrayList<Move>(); // ходы со взятием
  127.   Board board;
  128.  
  129.   Piece(Vec2Int position, Color col, boolean king) {
  130.     this.position = position;
  131.     this.col = col;
  132.     this.king = king;
  133.   }
  134.  
  135.   void findMovesAndCaptures() {
  136.     moves.clear();
  137.     captures.clear();
  138.     if (king) {
  139.       king_findMovesAndCaptures();
  140.     } else {
  141.       man_findMovesAndCaptures();
  142.     }
  143.   }
  144.  
  145.   void man_findMovesAndCaptures() {
  146.     for (Dir d: forwardDirs(col)) {
  147.       Vec2Int pos = position.add(d.vec);
  148.       if (!checkSquarePosition(pos)) continue;
  149.       Piece otherPiece = board.getPiece(pos);
  150.       if (otherPiece == null) {
  151.         moves.add(new Move(d, pos));
  152.       } else if (otherPiece.col != col && !otherPiece.captured) {
  153.         pos = pos.add(d.vec);
  154.         if (checkSquarePosition(pos) && board.getPiece(pos) == null) {
  155.           captures.add(new Move(d, pos, otherPiece));
  156.         }
  157.       }
  158.     }
  159.     for (Dir d: backwardDirs(col)) {
  160.       Vec2Int pos = position.add(d.vec);
  161.       if (!checkSquarePosition(pos)) continue;
  162.       Piece otherPiece = board.getPiece(pos);
  163.       if (otherPiece != null && otherPiece.col != col && !otherPiece.captured) {
  164.         pos = pos.add(d.vec);
  165.         if (checkSquarePosition(pos) && board.getPiece(pos) == null) {
  166.           captures.add(new Move(d, pos, otherPiece));
  167.         }
  168.       }
  169.     }
  170.   }
  171.  
  172.   void king_findMovesAndCaptures() {
  173.     for (Dir d: Dir.values()) {
  174.       Vec2Int pos = position;
  175.       while (true) {
  176.         pos = pos.add(d.vec);
  177.         if (!checkSquarePosition(pos)) break;
  178.         Piece otherPiece = board.getPiece(pos);
  179.         if (otherPiece == null) {
  180.           moves.add(new Move(d, pos));
  181.         } else {
  182.           if (otherPiece.col != col && !otherPiece.captured) {
  183.             Piece capturedPiece = otherPiece;
  184.             pos = pos.add(d.vec);
  185.             ArrayList<Move> singleCaptures = new ArrayList<Move>();
  186.             ArrayList<Move> doubleCaptures = new ArrayList<Move>();
  187.             while (checkSquarePosition(pos) && board.getPiece(pos) == null) {
  188.               Move move = new Move(d, pos, capturedPiece);
  189.               singleCaptures.add(move);
  190.               L:
  191.               for (Dir perpD: d.perpendiculars()) {
  192.                 Vec2Int perpPos = pos;
  193.                 while (true) {
  194.                   perpPos = perpPos.add(perpD.vec);
  195.                   if (!checkSquarePosition(perpPos)) break;
  196.                   otherPiece = board.getPiece(perpPos);
  197.                   if (otherPiece != null) {
  198.                     if (otherPiece.col != col && !otherPiece.captured) {
  199.                       perpPos = perpPos.add(perpD.vec);
  200.                       if (checkSquarePosition(perpPos) && board.getPiece(perpPos) == null) {
  201.                         doubleCaptures.add(move);
  202.                         break L;
  203.                       }
  204.                     }
  205.                     break;
  206.                   }
  207.                 }
  208.               }
  209.               pos = pos.add(d.vec);
  210.             }
  211.             if (doubleCaptures.size() > 0) {
  212.               captures.addAll(doubleCaptures);
  213.             } else {
  214.               captures.addAll(singleCaptures);
  215.             }
  216.           }
  217.           break;
  218.         }
  219.       }
  220.     }
  221.   }
  222.  
  223.   // есть ли среди найденных ходов ход в текущую клетку
  224.   Move getMove(Vec2Int position, boolean capturesFound) {
  225.     for (Move move: getMoveList(capturesFound)) {
  226.       if (move.position.equals(position)) {
  227.         return move;
  228.       }
  229.     }
  230.     return null;
  231.   }
  232.  
  233.   ArrayList<Move> getMoveList(boolean capturesFound) {
  234.     if (capturesFound) {
  235.       return captures;
  236.     } else {
  237.       return moves;
  238.     }
  239.   }
  240. }
  241.  
  242. class Board {
  243.   Piece[][] squares = new Piece[BoardSize][BoardSize];
  244.   LinkedList<Piece> whitePieces = new LinkedList<Piece>();
  245.   LinkedList<Piece> blackPieces = new LinkedList<Piece>();
  246.  
  247.   void addPiece(int x, int y, Color c, boolean king) {
  248.     if (squares[x][y] != null) throw new Error();
  249.     Piece piece = new Piece(new Vec2Int(x, y), c, king);
  250.     piece.board = this;
  251.     squares[x][y] = piece;
  252.     getPieces(c).add(piece);
  253.   }
  254.  
  255.   void addPiece(int x, int y, Color c) {
  256.     addPiece(x, y, c, false);
  257.   }
  258.  
  259.   Piece getPiece(Vec2Int position) {
  260.     return squares[position.x][position.y];
  261.   }
  262.  
  263.   void removePiece(Piece piece) {
  264.     getPieces(piece.col).remove(piece);
  265.     squares[piece.position.x][piece.position.y] = null;
  266.   }
  267.  
  268.   void movePiece(Piece piece, Vec2Int position) {
  269.     if (squares[position.x][position.y] != null) throw new Error();
  270.     squares[piece.position.x][piece.position.y] = null;
  271.     piece.position = position;
  272.     squares[piece.position.x][piece.position.y] = piece;
  273.   }
  274.  
  275.   LinkedList<Piece> getPieces(Color c) {
  276.     if (c == Color.White) {
  277.       return whitePieces;
  278.     } else {
  279.       return blackPieces;
  280.     }
  281.   }
  282. }
  283.  
  284. class Button {
  285.   int x;
  286.   int y;
  287.   int w;
  288.   int h = 30;
  289.   String text;
  290.   boolean pressed = false;
  291.   boolean enabled = true;
  292.  
  293.   Button(int x, int y, int w, String t) {
  294.     this.x = x;
  295.     this.y = y;
  296.     this.w = w;
  297.     this.text = t;
  298.   }
  299.  
  300.   void draw() {
  301.     if (!enabled) return;
  302.     noStroke();
  303.     if (mouseOver()) {
  304.       fill(200);
  305.     } else {
  306.       fill(150);
  307.     }
  308.     rect(x, y, w, h, 5);
  309.     fill(0);
  310.     textSize(16);
  311.     textAlign(CENTER, CENTER);
  312.     text(text, x + w / 2, y + h / 2);
  313.   }
  314.  
  315.   void mousePressed() {
  316.     if (!enabled) return;
  317.     if (mouseOver()) {
  318.       pressed = true;
  319.     }
  320.   }
  321.  
  322.   boolean mouseOver() {
  323.     if (!enabled) return false;
  324.     return mouseX >= x && mouseX < (x + w - 1) && mouseY >= y && mouseY < (y + h - 1);
  325.   }
  326. }
  327.  
  328. class ButtonGroup {
  329.   ArrayList<Button> buttons = new ArrayList<Button>();
  330.  
  331.   void add(Button b) {
  332.     buttons.add(b);
  333.   }
  334.  
  335.   void draw() {
  336.     for (Button b: buttons) {
  337.       b.draw();
  338.     }
  339.   }
  340.  
  341.   void mousePressed() {
  342.     for (Button b: buttons) {
  343.       b.mousePressed();
  344.     }
  345.   }
  346. }
  347.  
  348. interface Scene {
  349.   void init();
  350.   void draw();
  351.   void mousePressed();
  352. }
  353.  
  354. class Menu implements Scene {
  355.   ButtonGroup buttons = new ButtonGroup();
  356.   Button playWhiteBtn;
  357.   Button playBlackBtn;
  358.   Button twoPersonsBtn;
  359.   Button twoBotsBtn;
  360.   Button editorBtn;
  361.  
  362.   Menu() {
  363.     int bX = 20;
  364.     int bW = 180;
  365.     playWhiteBtn = new Button(bX, 100, bW, "Играть за белых");
  366.     playBlackBtn = new Button(bX, 140, bW, "Играть за черных");
  367.     twoPersonsBtn = new Button(bX, 180, bW, "Играть вдвоем");
  368.     twoBotsBtn = new Button(bX, 220, bW, "Игра ботов");
  369.     editorBtn = new Button(bX, 260, bW, "Редактор");
  370.     buttons.add(playWhiteBtn);
  371.     buttons.add(playBlackBtn);
  372.     buttons.add(twoPersonsBtn);
  373.     buttons.add(twoBotsBtn);
  374.     buttons.add(editorBtn);
  375.   }
  376.  
  377.   void init() {
  378.   }
  379.  
  380.   void draw() {
  381.     background(BgColor);
  382.     fill(0);
  383.     textAlign(CENTER);
  384.     textSize(32);
  385.     text("Русские Шашки", width / 2, 50);
  386.     buttons.draw();
  387.   }
  388.  
  389.   void mousePressed() {
  390.     loadGameFromEditor = false;
  391.     if (playWhiteBtn.mouseOver()) {
  392.       whitePlayerT = PlayerT.Person;
  393.       blackPlayerT = PlayerT.Bot;
  394.       loadScene(game);
  395.     } else if (playBlackBtn.mouseOver()) {
  396.       whitePlayerT = PlayerT.Bot;
  397.       blackPlayerT = PlayerT.Person;
  398.       loadScene(game);
  399.     } else if (twoPersonsBtn.mouseOver()) {
  400.       whitePlayerT = PlayerT.Person;
  401.       blackPlayerT = PlayerT.Person;
  402.       loadScene(game);
  403.     } else if (twoBotsBtn.mouseOver()) {
  404.       whitePlayerT = PlayerT.Bot;
  405.       blackPlayerT = PlayerT.Bot;
  406.       loadScene(game);
  407.     } else if (editorBtn.mouseOver()) {
  408.       loadScene(editor);
  409.     }
  410.   }
  411. }
  412.  
  413. class GameState {
  414.   void init() {};
  415.   void update() {};
  416.   void mousePressed(Vec2Int currentSquare) {};
  417. }
  418.  
  419. class Game implements Scene {
  420.   Board board;
  421.   ArrayList<Piece> capturedPieces; // битые шашки
  422.   ArrayList<Piece> availablePieces; // доступные для очередного хода шашки
  423.   ArrayList<Vec2Int> lastMoves; // ход последней шашки
  424.   ArrayList<Vec2Int> lastCapturedPieces; // и сбитые ей шашки
  425.   boolean gameFinished;
  426.   Color winner;
  427.  
  428.   // устанавливаются в setPlayer()
  429.   Color currentPlayer;
  430.   Piece selectedPiece;
  431.   Move selectedMove;
  432.   boolean capturesFound; // если обнаружены ходы со взятием, то выбирать можно только из них
  433.   boolean multipleCapture; // последовательное взятие
  434.  
  435.   final int FramesPerSquare = 5; // скорость перемещения шашки на одну клетку
  436.   float movedPieceProgress; // пройденная дистанция шашки (1 клетка - 1 единица)
  437.  
  438.   GameState st_PersonInput = new State_PersonInput();
  439.   GameState st_BotInput = new State_BotInput();
  440.   GameState st_MovePiece = new State_MovePiece();
  441.  
  442.   GameState currentState;
  443.  
  444.   ButtonGroup buttons = new ButtonGroup();
  445.   Button menuBtn;
  446.   Button resetBtn;
  447.   Button editorBtn;
  448.  
  449.   Game() {
  450.     menuBtn = new Button(20, height - 40, 100, "Меню");
  451.     resetBtn = new Button(140, height - 40, 160, "Перезапустить");
  452.     editorBtn = new Button(320, height - 40, 120, "Редактор");
  453.     buttons.add(menuBtn);
  454.     buttons.add(resetBtn);
  455.     buttons.add(editorBtn);
  456.   }
  457.  
  458.   void init() {
  459.     board = new Board();
  460.     capturedPieces = new ArrayList<Piece>();
  461.     availablePieces = new ArrayList<Piece>();
  462.     lastMoves = new ArrayList<Vec2Int>();
  463.     lastCapturedPieces = new ArrayList<Vec2Int>();
  464.     gameFinished = false;
  465.     if (loadGameFromEditor) { // загрузить расстановку шашек из редактора
  466.       editorBtn.enabled = true;
  467.       for (int x = 0; x < BoardSize; ++x) {
  468.         for (int y = 0; y < BoardSize; ++y) {
  469.           switch (editor.boardData[x][y]) {
  470.             case Editor.WhiteMan:
  471.               board.addPiece(x, y, Color.White);
  472.               break;
  473.             case Editor.WhiteKing:
  474.               board.addPiece(x, y, Color.White, true);
  475.               break;
  476.             case Editor.BlackMan:
  477.               board.addPiece(x, y, Color.Black);
  478.               break;
  479.             case Editor.BlackKing:
  480.               board.addPiece(x, y, Color.Black, true);
  481.               break;
  482.           }
  483.         }
  484.       }
  485.     } else { // расставить шашки стандартно
  486.       editorBtn.enabled = false;
  487.       Color c = Color.Black;
  488.       board.addPiece(1, 0, c);
  489.       board.addPiece(3, 0, c);
  490.       board.addPiece(5, 0, c);
  491.       board.addPiece(7, 0, c);
  492.       board.addPiece(0, 1, c);
  493.       board.addPiece(2, 1, c);
  494.       board.addPiece(4, 1, c);
  495.       board.addPiece(6, 1, c);
  496.       board.addPiece(1, 2, c);
  497.       board.addPiece(3, 2, c);
  498.       board.addPiece(5, 2, c);
  499.       board.addPiece(7, 2, c);
  500.       c = Color.White;
  501.       board.addPiece(0, 5, c);
  502.       board.addPiece(2, 5, c);
  503.       board.addPiece(4, 5, c);
  504.       board.addPiece(6, 5, c);
  505.       board.addPiece(1, 6, c);
  506.       board.addPiece(3, 6, c);
  507.       board.addPiece(5, 6, c);
  508.       board.addPiece(7, 6, c);
  509.       board.addPiece(0, 7, c);
  510.       board.addPiece(2, 7, c);
  511.       board.addPiece(4, 7, c);
  512.       board.addPiece(6, 7, c);
  513.     }
  514.     setPlayer(Color.White);
  515.     setPlayerInputState();
  516.   }
  517.  
  518.   void draw() {
  519.     if (!gameFinished) {
  520.       currentState.update();
  521.     }
  522.     background(BgColor);
  523.     drawBoard();
  524.     // предыдущий ход
  525.     for (int i = 0; i < lastMoves.size() - 1; ++i) {
  526.       stroke(0, 0, 255);
  527.       strokeWeight(2);
  528.       Vec2Int p1 = lastMoves.get(i);
  529.       Vec2Int p2 = lastMoves.get(i + 1);
  530.       line((p1.x + 0.5) * SquareSize, (p1.y + 0.5) * SquareSize, (p2.x + 0.5) * SquareSize, (p2.y + 0.5) * SquareSize);
  531.     }
  532.     for (Vec2Int p: lastCapturedPieces) {
  533.       noStroke();
  534.       fill(0, 0, 255, 100);
  535.       ellipse((p.x + 0.5) * SquareSize, (p.y + 0.5) * SquareSize, PieceSize, PieceSize);
  536.     }
  537.     // шашки
  538.     for (int x = 0; x < BoardSize; ++x) {
  539.       for (int y = 0; y < BoardSize; ++y) {
  540.         Piece piece = board.squares[x][y];
  541.         if (piece != null) {
  542.           // если идет анимащия хода шашки, то эта шашка рисуется отдельно
  543.           if (selectedMove != null && piece == selectedPiece) {
  544.             continue;
  545.           }
  546.           drawPiece(x, y, piece.col == Color.White, piece.king);
  547.           if (piece.captured) {
  548.             stroke(255, 0, 0);
  549.             strokeWeight(2);
  550.             float crossX1 = x * SquareSize;
  551.             float crossY1 = y * SquareSize;
  552.             float crossX2 = crossX1 + SquareSize;
  553.             float crossY2 = crossY1 + SquareSize;
  554.             line(crossX1, crossY1, crossX2, crossY2);
  555.             line(crossX2, crossY1, crossX1, crossY2);
  556.           }
  557.         }
  558.       }
  559.     }
  560.     // выделение шашек, которыми можно ходить
  561.     if (!multipleCapture && selectedMove == null) {
  562.       if (currentPlayerType() == PlayerT.Person) {
  563.         stroke(255, 255, 0);
  564.       } else {
  565.         stroke(200, 0, 255);
  566.       }
  567.       strokeWeight(2);
  568.       noFill();
  569.       for (Piece piece: board.getPieces(currentPlayer)) {
  570.         boolean pieceAvailable = false;
  571.         if (capturesFound) {
  572.           pieceAvailable = piece.captures.size() > 0;
  573.         } else {
  574.           pieceAvailable = piece.moves.size() > 0;
  575.         }
  576.         if (pieceAvailable) {
  577.           rect(piece.position.x * SquareSize, piece.position.y * SquareSize, SquareSize, SquareSize);
  578.         }
  579.       }
  580.     }
  581.     // выделение выбранной шашки
  582.     if (selectedPiece != null) {
  583.       noFill();
  584.       stroke(0, 255, 0);
  585.       strokeWeight(2);
  586.       rect(selectedPiece.position.x * SquareSize, selectedPiece.position.y * SquareSize, SquareSize, SquareSize);
  587.       for (Move move: selectedPiece.getMoveList(capturesFound)) {
  588.         ellipse((move.position.x + 0.5) * SquareSize, (move.position.y + 0.5) * SquareSize, PieceSize, PieceSize);
  589.       }
  590.     }
  591.     // анимация хода шашки
  592.     if (selectedMove != null) {
  593.       pushMatrix();
  594.       Dir d = selectedMove.direction;
  595.       float dist = movedPieceProgress * SquareSize;
  596.       translate(d.vec.x * dist, d.vec.y * dist);
  597.       Vec2Int pos = selectedPiece.position;
  598.       drawPiece(pos.x, pos.y, selectedPiece.col == Color.White, selectedPiece.king);
  599.       popMatrix();
  600.     }
  601.     // UI
  602.     drawPiece(BoardSize + 1, 1, false, false);
  603.     drawPiece(BoardSize + 1, 2, true, false);
  604.     fill(0);
  605.     textSize(32);
  606.     textAlign(CENTER, CENTER);
  607.     text(Integer.toString(board.blackPieces.size()), (BoardSize + 2.5) * SquareSize, 1.5 * SquareSize);
  608.     text(Integer.toString(board.whitePieces.size()), (BoardSize + 2.5) * SquareSize, 2.5 * SquareSize);
  609.     if (gameFinished) {
  610.       textAlign(CENTER, TOP);
  611.       if (winner == Color.White) {
  612.         text("Победили белые", (BoardSize / 2) * SquareSize, BoardSize * SquareSize + 10);
  613.       } else {
  614.         text("Победили черные", (BoardSize / 2) * SquareSize, BoardSize * SquareSize + 10);
  615.       }
  616.     }
  617.     buttons.draw();
  618.   }
  619.  
  620.   void mousePressed() {
  621.     if (!gameFinished && mouseButton == LEFT) {
  622.       Vec2Int square = new Vec2Int(floor(mouseX / SquareSize), floor(mouseY / SquareSize));
  623.       if (checkSquarePosition(square)) {
  624.         currentState.mousePressed(square);
  625.       }
  626.     }
  627.     if (menuBtn.mouseOver()) {
  628.       loadScene(menu);
  629.     } else if (resetBtn.mouseOver()) {
  630.       loadScene(game);
  631.     } else if (editorBtn.mouseOver()) {
  632.       loadScene(editor);
  633.     }
  634.   }
  635.  
  636.   void markCaptured(Piece piece) {
  637.     piece.captured = true;
  638.     capturedPieces.add(piece);
  639.   }
  640.  
  641.   void movePiece(Piece piece, Vec2Int position) {
  642.     board.movePiece(piece, position);
  643.     if (piece.position.y == lastRow(piece.col)) {
  644.       piece.king = true;
  645.     }
  646.   }
  647.  
  648.   void setPlayer(Color c) {
  649.     currentPlayer = c;
  650.     selectedPiece = null;
  651.     selectedMove = null;
  652.     multipleCapture = false;
  653.     capturesFound = false;
  654.     for (Piece piece: board.getPieces(c)) {
  655.       piece.findMovesAndCaptures();
  656.       if (piece.captures.size() > 0) {
  657.         capturesFound = true;
  658.       }
  659.     }
  660.     availablePieces.clear();
  661.     for (Piece piece: board.getPieces(c)) {
  662.       if (piece.getMoveList(capturesFound).size() > 0) {
  663.         availablePieces.add(piece);
  664.       }
  665.     }
  666.     if (availablePieces.size() == 0) {
  667.       gameFinished = true;
  668.       winner = c.getInverse();
  669.     }
  670.   }
  671.  
  672.   void switchPlayer() {
  673.     for (Piece piece: capturedPieces) {
  674.       lastCapturedPieces.add(piece.position);
  675.       board.removePiece(piece);
  676.     }
  677.     capturedPieces.clear();
  678.     setPlayer(currentPlayer.getInverse());
  679.   }
  680.  
  681.   void setState(GameState state) {
  682.     currentState = state;
  683.     currentState.init();
  684.   }
  685.  
  686.   PlayerT currentPlayerType() {
  687.     return currentPlayer == Color.White ? whitePlayerT : blackPlayerT;
  688.   }
  689.  
  690.   void setPlayerInputState() {
  691.     if (currentPlayerType() == PlayerT.Person) {
  692.       setState(st_PersonInput);
  693.     } else {
  694.       setState(st_BotInput);
  695.     }
  696.   }
  697.  
  698.   class State_PersonInput extends GameState {
  699.    
  700.     @Override
  701.     void mousePressed(Vec2Int currentSquare) {
  702.       if (multipleCapture) { // можно только походить выбранной шашкой
  703.         Move availableMove = selectedPiece.getMove(currentSquare, true);
  704.         if (availableMove != null) {
  705.           selectedMove = availableMove;
  706.           setState(st_MovePiece);
  707.         }
  708.       } else { // можно выбрать шашку, сменить выбранную шашку, походить
  709.         Piece piece = board.getPiece(currentSquare);
  710.         if (piece != null) {
  711.           if (piece.col == currentPlayer && piece.getMoveList(capturesFound).size() > 0) {
  712.             selectedPiece = piece;
  713.           }
  714.         } else if (selectedPiece != null) {
  715.           Move availableMove = selectedPiece.getMove(currentSquare, capturesFound);
  716.           if (availableMove != null) {
  717.             selectedMove = availableMove;
  718.             setState(st_MovePiece);
  719.           }
  720.         }
  721.       }
  722.     }
  723.   }
  724.  
  725.   class State_BotInput extends GameState {
  726.     final int delay = 40;
  727.     int time;
  728.    
  729.     @Override()
  730.     void init() {
  731.       time = 0;
  732.     }
  733.    
  734.     @Override
  735.     void update() {
  736.       ++time;
  737.       if (time > delay) {
  738.         if (selectedPiece == null) { // выбрать шашку
  739.           int i = floor(random(availablePieces.size()));
  740.           selectedPiece = availablePieces.get(i);
  741.           time = 0;
  742.         } else { // выбрать ход
  743.           ArrayList<Move> availableMoves = selectedPiece.getMoveList(capturesFound);
  744.           int i = floor(random(availableMoves.size()));
  745.           selectedMove = availableMoves.get(i);
  746.           setState(st_MovePiece);
  747.         }
  748.       }
  749.     }
  750.   }
  751.  
  752.   class State_MovePiece extends GameState {
  753.     int time;
  754.     int duration;
  755.    
  756.     @Override
  757.     void init() {
  758.       time = 0;
  759.       duration = abs(selectedMove.position.x - selectedPiece.position.x) * FramesPerSquare;
  760.       if (!multipleCapture) {
  761.         lastMoves.clear();
  762.         lastMoves.add(selectedPiece.position);
  763.         lastCapturedPieces.clear();
  764.       }
  765.       lastMoves.add(selectedMove.position);
  766.     }
  767.    
  768.     @Override
  769.     void update() {
  770.       ++time;
  771.       if (time < duration) {
  772.         movedPieceProgress = (float)time / FramesPerSquare;
  773.       } else {
  774.         movedPieceProgress = 0;
  775.         movePiece(selectedPiece, selectedMove.position);
  776.         if (selectedMove.capturedPiece != null) {
  777.           markCaptured(selectedMove.capturedPiece);
  778.           selectedPiece.findMovesAndCaptures();
  779.           if (selectedPiece.captures.size() == 0) {
  780.             switchPlayer();
  781.           } else {
  782.             multipleCapture = true;
  783.           }
  784.         } else {
  785.           switchPlayer();
  786.         }
  787.         selectedMove = null;
  788.         setPlayerInputState();
  789.       }
  790.     }
  791.   }
  792. }
  793.  
  794. class Editor implements Scene {
  795.   static final int Empty     = 0;
  796.   static final int WhiteMan  = 1;
  797.   static final int WhiteKing = 2;
  798.   static final int BlackMan  = 3;
  799.   static final int BlackKing = 4;
  800.   static final int PieceTypeNum = 5;
  801.  
  802.   int boardData[][] = new int[BoardSize][BoardSize];
  803.   int pieceType = WhiteMan;
  804.   int pieceTypeSquareX = BoardSize + 1;
  805.  
  806.   ButtonGroup buttons = new ButtonGroup();
  807.   Button menuBtn;
  808.   Button testBtn;
  809.  
  810.   Editor() {
  811.     menuBtn = new Button(20, height - 40, 100, "Меню");
  812.     testBtn = new Button(140, height - 40 , 100, "Тест");
  813.     buttons.add(menuBtn);
  814.     buttons.add(testBtn);
  815.   }
  816.  
  817.   void init() {
  818.   }
  819.  
  820.   void draw() {
  821.     background(BgColor);
  822.     drawBoard();
  823.     for (int x = 0; x < BoardSize; ++x) {
  824.       for (int y = 0; y < BoardSize; ++y) {
  825.         switch (boardData[x][y]) {
  826.           case WhiteMan:
  827.             drawPiece(x, y, true, false);
  828.             break;
  829.           case WhiteKing:
  830.             drawPiece(x, y, true, true);
  831.             break;
  832.           case BlackMan:
  833.             drawPiece(x, y, false, false);
  834.             break;
  835.           case BlackKing:
  836.             drawPiece(x, y, false, true);
  837.             break;
  838.         }
  839.       }
  840.     }
  841.     drawPiece(pieceTypeSquareX, WhiteMan, true, false);
  842.     drawPiece(pieceTypeSquareX, WhiteKing, true, true);
  843.     drawPiece(pieceTypeSquareX, BlackMan, false, false);
  844.     drawPiece(pieceTypeSquareX, BlackKing, false, true);
  845.     stroke(0, 255, 0);
  846.     strokeWeight(2);
  847.     noFill();
  848.     rect(pieceTypeSquareX * SquareSize, pieceType * SquareSize, SquareSize, SquareSize);
  849.     fill(0);
  850.     textSize(16);
  851.     textAlign(LEFT, TOP);
  852.     text("ЛКМ - поставить шашку", 20, BoardSize * SquareSize + 10);
  853.     text("ПКМ - убрать шашку", 20, BoardSize * SquareSize + 30);
  854.     buttons.draw();
  855.   }
  856.  
  857.   void mousePressed() {
  858.     Vec2Int currentSquare = new Vec2Int(floor(mouseX / SquareSize), floor(mouseY / SquareSize));
  859.     if (checkSquarePosition(currentSquare)) {
  860.       if (mouseButton == LEFT) {
  861.         boardData[currentSquare.x][currentSquare.y] = pieceType;
  862.       } else if (mouseButton == RIGHT) {
  863.         boardData[currentSquare.x][currentSquare.y] = Empty;
  864.       }
  865.     } else if (currentSquare.x == pieceTypeSquareX && currentSquare.y > 0 && currentSquare.y < PieceTypeNum) {
  866.       pieceType = currentSquare.y;
  867.     }
  868.     if (menuBtn.mouseOver()) {
  869.       loadScene(menu);
  870.     } else if (testBtn.mouseOver()) {
  871.       loadGameFromEditor = true;
  872.       whitePlayerT = PlayerT.Person;
  873.       blackPlayerT = PlayerT.Person;
  874.       loadScene(game);
  875.     }
  876.   }
  877. }
  878.  
  879. void setup() {
  880.   size(600, 500);
  881.   menu = new Menu();
  882.   game = new Game();
  883.   editor = new Editor();
  884.   loadScene(menu);
  885. }
  886.  
  887. void draw() {
  888.   currentScene.draw();
  889. }
  890.  
  891. void mousePressed() {
  892.   currentScene.mousePressed();
  893. }
  894.  
  895. void loadScene(Scene s) {
  896.   currentScene = s;
  897.   currentScene.init();
  898. }
  899.  
  900. boolean checkSquarePosition(Vec2Int p) {
  901.   return p.x >= 0 && p.x < BoardSize && p.y >= 0 && p.y < BoardSize;
  902. }
  903.  
  904. void drawBoard() {
  905.   for (int x = 0; x < BoardSize; ++x) {
  906.     for (int y = 0; y < BoardSize; ++y) {
  907.       if (x % 2 != y % 2) {
  908.         fill(150);  
  909.       } else {
  910.         fill(220);
  911.       }
  912.       noStroke();
  913.       rect(x * SquareSize, y * SquareSize, SquareSize, SquareSize);
  914.     }
  915.   }
  916. }
  917.  
  918. void drawPiece(int x, int y, boolean white, boolean king) {
  919.   stroke(0);
  920.   strokeWeight(2);
  921.   fill(white ? 255 : 0);
  922.   float centerX = (x + 0.5) * SquareSize;
  923.   float centerY = (y + 0.5) * SquareSize;
  924.   ellipse(centerX, centerY, PieceSize, PieceSize);
  925.   if (king) {
  926.     noStroke();
  927.     fill(white ? 0 : 255);
  928.     float dotSize = PieceSize * 0.3;
  929.     ellipse(centerX, centerY, dotSize, dotSize);
  930.   }
  931. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement