Compare commits

..
12 Commits
Author SHA1 Message Date
lin 80626485ca updated UML 2026-10-19 04:15:55 +02:00
lin 5663b2285a Implemented type enum 2026-10-19 04:10:56 +02:00
lin d025c31789 Implemented direction enum 2026-10-19 04:10:40 +02:00
lin 040f5e1b87 Implemented color enum 2026-10-19 04:10:29 +02:00
lin f14920f03a Implemented piece logic 2026-10-19 04:10:19 +02:00
lin a117de01fc updated uml 2026-10-19 04:09:38 +02:00
lin a5ea95e5bd Instead of html embed I use markdown native embeds for uml 2026-10-19 02:46:34 +02:00
lin e9f763877c Project plan completed 2026-10-19 02:40:04 +02:00
lin a3b8a267e8 Updated readme to represent requirements 2026-10-16 20:28:10 +02:00
lin 52e9baabae Merge pull request 'Master' (#1) from master into main
Reviewed-on: #1
2026-10-13 15:55:03 +01:00
lin 0f8edaa6f8 Merge branch 'main' of https://gitea.tailb5c20b.ts.net/lin/gui-chess 2026-10-13 16:53:25 +02:00
lin faa65c2014 Initial commit 2026-10-13 15:45:36 +01:00
15 changed files with 680 additions and 0 deletions

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
# ---> Java
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
+18
View File
@@ -0,0 +1,18 @@
MIT License
Copyright (c) 2026 lin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
+77
View File
@@ -0,0 +1,77 @@
# Sakk alkalmazás (gui-chess)
Programozás alapjai 3 – Nagy házi feladat specifikáció
## 1. Célkitűzés
A projekt célja egy teljes körű sakkalkalmazás implementálása Java nyelven. A feladat alapját a „Programozás alapjai 2” tárgyban készült C++ sakkmotor adja, melynek logikáját átemelve, az objektumorientált elveket és a Java nyelvi sajátosságait kihasználva egy grafikus felhasználói felülettel (GUI) és parancssori réteggel is rendelkező szoftver készül.
## 2. Funkcionális követelmények
### 2.1 Játékszabályok és játékmódok
- Szabályrendszer: A standard sakk szabályainak teljes körű ellenőrzése és betartatása (szabályos lépések, sakk, matt, patt helyzetek detektálása, sáncolás, en passant és gyalogátváltozás).
- Játékos módok: Lokális kétfős játék (Hotseat mód), ahol a felek felváltva lépnek ugyanazon a felületen.
- Lépésvisszavonás és elemzés: Lehetőség a lépések visszavonására (Undo) és előreléptetésére.
### 2.2 Felhasználói felületek
- Grafikus felület (GUI):
- Interaktív sakktábla (kattintásos vagy drag-and-drop bábulépéssel).
- Vizuális visszajelzés az érvényes lépésekről és az aktuális sakkhelyzetről.
- Lépéslista (Move history) megjelenítése algebrai jelöléssel.
- Konzolos felület (CLI):
- A sakktábla kirajzolása terminálban szöveges karakterekkel.
- Lépések fogadása standard szöveges formátumban (pl. `e2e4`).
### 2.3. Adatkezelés és perzisztencia
- PGN (Portable Game Notation) támogatás:
- Külső forrásból származó (pl. [Chess.com](https://chess.com), [Lichess](https://lichess.org)) standard `.pgn` formátumú játszmák beolvasása, elemzése és visszajátszása.
- Az aktuálisan játszott parti kimentése szabványos PGN fájlba a metaadatokkal (dátum, felek nevei, eredmény) együtt.
- Állásmentés (FEN): Az aktuális táblaállás gyors betöltése és exportálása FEN (Forsyth–Edwards Notation) karakterlánccal.
## 3. Nem funkcionális követelmények és architektúra
- Választott architektúra (MVC):
- Model: A sakktábla állapota, szabályellenőrzés, bábuk reprezentációja és lépésgenerálás. A motor teljesen független a megjelenítéstől.
- View: `Java Swing` komponensek és a CLI kirajzoló modul.
- Controller: Eseménykezelők, amelyek a felhasználói beviteleket (GUI kattintás, CLI parancs) továbbítják a motornak.
- Perzisztencia / Fájlkezelés: Szabványos Java I/O, kivételkezeléssel.
- Tesztelhetőség: A játékmotor üzleti logikáját (speciális lépések, matt detektálás, PGN parser) lefedő JUnit egységtesztek.
## 4. Terv
### 4.1 Szereplők
- Játékos: Az a személy aki játszmát kezdeményez, lépéseket tesz, kezeli a játék felületét.
- Fájlrendszer: Másodlagos szereplő. PGN/FEN állományokat kezel.
### 4.2 Használati esetek (Use Cases):
- Új játszma indítása
- Lépés megtétele a táblán
- Lehetséges lépések megtekintése
- Lépés visszavonása
- Játszma mentése (PGN formátumban)
- Játszma betöltése és visszajátszása (PGN formátumból)
- Táblaállás betöltése/mentése (FEN formátumból/ban)
### 4.3 GUI váza:
```text
+-------------------------------------------------------------+
| Menüsor: [Fájl (Új, Betöltés, Mentés)] [Nézet] [Segítség] |
+-------------------------------------------------------------+
| +---------------------------+ +------------------------+ |
| | | | Státusz / Soron lévő: | |
| | | | Fehér | |
| | | | Sakk jelzés: Nincs | |
| | | +------------------------+ |
| | | | Lépéstörténet: | |
| | SAKKTÁBLA | | 1. e4 e5 | |
| | (8 x 8) | | 2. Nf3 Nc6 | |
| | | | 3. Bb5 ... | |
| | | +------------------------+ |
| | | | Vezérlők: | |
| | | | [< Előző] [Következő >]| |
| | | | [Undo] | |
| +---------------------------+ +------------------------+ |
+-------------------------------------------------------------+
```
### 4.4 UML
![UML diagram](assets/Diagram.svg)
+286
View File
@@ -0,0 +1,286 @@
<mxfile host="app.diagrams.net">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Oldal-1">
<mxGraphModel dx="1857" dy="1780" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="_r-HP5b758gAeptMtzsk-38" parent="WIyWlLk6GJQsqaUBKTNV-1" style="shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;whiteSpace=wrap;fillColor=default;" value="" vertex="1">
<mxGeometry height="880" width="1750" x="-500" y="-370" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-0" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Abstract»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Piece&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- pieceColor: Color&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- movedBefore: boolean&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ Piece(Color)&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getMoveDomain() : Direction[]&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getColor() : Color&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getSymbol() : Char&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getType() : Type&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ hasMoved() : bool&lt;/p&gt;" vertex="1">
<mxGeometry height="170" width="260" x="250" y="-30" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-3" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Pawn&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="-486" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-4" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;King&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="-176" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-5" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Queen&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="126" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-6" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Rook&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="429" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-7" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Bishop&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="734" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-12" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-3" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" as="geometry">
<mxPoint x="340" y="280" as="sourcePoint" />
<mxPoint x="500" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-13" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-4" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" as="geometry">
<mxPoint x="10" y="470" as="sourcePoint" />
<mxPoint x="525" y="290" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-14" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-5" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" x="-0.1252" as="geometry">
<mxPoint x="390" y="450" as="sourcePoint" />
<mxPoint x="655" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-15" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-6" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" as="geometry">
<mxPoint x="480" y="460" as="sourcePoint" />
<mxPoint x="410" y="131.12" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-16" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-7" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=1;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" as="geometry">
<mxPoint x="720" y="420" as="sourcePoint" />
<mxPoint x="985" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-18" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-19" style="endArrow=block;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;curveGeometry=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" as="geometry">
<mxPoint x="1015" y="390" as="sourcePoint" />
<mxPoint x="1085" y="230" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-19" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Knight&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&amp;nbsp;+ getMoveDomain() : Direction[]" vertex="1">
<mxGeometry height="70" width="176" x="1054" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-20" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;«Enum»&lt;/p&gt;&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;Type&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;PAWN&lt;br&gt;KING&lt;br&gt;QUEEN&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;ROOK&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;BISHOP&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;KNIGHT&lt;/p&gt;" vertex="1">
<mxGeometry height="140" width="60" x="90" y="-115" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-22" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;«Enum»&lt;/p&gt;&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;Color&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;div&gt;&amp;nbsp;WHITE&lt;/div&gt;&lt;div&gt;&amp;nbsp;BLACK&lt;/div&gt;" vertex="1">
<mxGeometry height="80" width="50" x="355" y="-270" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-26" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-20" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.001;entryY=0.595;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;entryPerimeter=0;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-0" value="Use">
<mxGeometry relative="1" width="160" x="0.0023" as="geometry">
<Array as="points">
<mxPoint x="200" y="-45" />
<mxPoint x="200" y="71" />
</Array>
<mxPoint x="140" y="170" as="sourcePoint" />
<mxPoint x="300" y="170" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-27" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-22" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;startArrow=none;startFill=0;startSize=12;exitX=0.5;exitY=1;exitDx=0;exitDy=0;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" width="160" x="-0.063" as="geometry">
<mxPoint x="70" y="-160" as="sourcePoint" />
<mxPoint x="300" y="170" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-29" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ChessBoard&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- board: Piece[64]&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ ChessBoard()&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getPiece(idx : int) : Piece&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getPiece(x : int, y : int) : Piece&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ movePiece(from: int, to: int) : Optional&amp;lt;Move&amp;gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ isCheck(color : Color) : bool&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ isCheckMate(color : Color) : bool&lt;/p&gt;" vertex="1">
<mxGeometry height="170" width="260" x="640" y="-340" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-30" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-29" style="endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;rounded=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-0" value="">
<mxGeometry relative="1" x="-0.542" y="3" as="geometry">
<Array as="points">
<mxPoint x="770" y="-95" />
<mxPoint x="445" y="-95" />
</Array>
<mxPoint x="700" y="-120" as="sourcePoint" />
<mxPoint x="740" y="-220" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-31" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="1" vertex="1">
<mxGeometry height="30" width="60" x="750" y="-160" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-32" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="0..64" vertex="1">
<mxGeometry height="30" width="60" x="440" y="-60" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-37" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-22" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=0.977;exitY=0.176;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;libavoidRouting=1;exitPerimeter=0;" target="_r-HP5b758gAeptMtzsk-29" value="Use">
<mxGeometry relative="1" width="160" x="-0.0132" as="geometry">
<Array as="points">
<mxPoint x="523" y="-256" />
<mxPoint x="523" y="-255" />
</Array>
<mxPoint x="300" y="-300" as="sourcePoint" />
<mxPoint x="550" y="-115" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-39" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;strokeWidth=1;fontSize=24;" value="&lt;div&gt;Model&lt;/div&gt;" vertex="1">
<mxGeometry height="55" width="113" x="-500" y="-360" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-40" parent="WIyWlLk6GJQsqaUBKTNV-1" style="shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;whiteSpace=wrap;fillColor=default;" value="" vertex="1">
<mxGeometry height="490" width="450" x="1350" y="-280" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-41" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontSize=24;" value="Controller" vertex="1">
<mxGeometry height="30" width="60" x="1380" y="-260" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-46" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1.003;entryY=0.395;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;fontSize=11;startSize=6;endSize=12;exitX=0;exitY=0.25;exitDx=0;exitDy=0;" target="_r-HP5b758gAeptMtzsk-29">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1420" y="-191" />
<mxPoint x="1310" y="-191" />
<mxPoint x="1310" y="-272.8" />
</Array>
<mxPoint x="1790" y="-210" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-1" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;libavoidRouting=1;startArrow=diamondThin;startFill=1;endArrow=open;endFill=0;startSize=14;endSize=12;" target="oEUtffCDIGD-I46B6jyE-0">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1290" y="-97" />
<mxPoint x="1290" y="-130" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-47" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«&lt;i&gt;Final&lt;/i&gt;»&lt;br&gt;&lt;b&gt;ChessGame&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- board: ChessBoard&lt;br&gt;- state: GameState&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- view: GameView&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- history: List&amp;lt;Move&amp;gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ start(): void&lt;br&gt;+ processTurn(from: int, to: int) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ getGameState() : GameState&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&lt;br&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- endTurn() : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- switchPlayer() : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- checkGameEnd() : void&lt;/p&gt;" vertex="1">
<mxGeometry height="236" width="220" x="1370" y="-215" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-49" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«&lt;i&gt;Final&lt;/i&gt;»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«&lt;i&gt;Record&lt;/i&gt;»&lt;br&gt;&lt;b&gt;GameState&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;activePlayer: Color&lt;br&gt;status: GameStatus&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&lt;br&gt;&lt;/p&gt;" vertex="1">
<mxGeometry height="100" width="190" x="1480" y="100" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-50" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;libavoidRouting=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" target="_r-HP5b758gAeptMtzsk-49" value="">
<mxGeometry relative="1" x="-0.7356" y="3" as="geometry">
<Array as="points">
<mxPoint x="1480" y="73" />
<mxPoint x="1575" y="73" />
</Array>
<mxPoint x="1587" y="-67" as="sourcePoint" />
<mxPoint x="1360" y="70" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-51" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="1" vertex="1">
<mxGeometry height="15" width="30" x="1480" y="30" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-52" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="1" vertex="1">
<mxGeometry height="15" width="20" x="1580" y="80" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-54" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;«Enum»&lt;/p&gt;&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;GameStatus&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;div&gt;&amp;nbsp;ACTIVE&lt;/div&gt;&lt;div&gt;&amp;nbsp;WHITE_WINS&lt;/div&gt;&lt;div&gt;&amp;nbsp;BLACK_WINS&lt;/div&gt;&lt;div&gt;&amp;nbsp;STALEMATE&lt;/div&gt;" vertex="1">
<mxGeometry height="110" width="90" x="1680" y="-130" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-56" parent="WIyWlLk6GJQsqaUBKTNV-1" style="shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;whiteSpace=wrap;fillColor=default;" value="" vertex="1">
<mxGeometry height="570" width="620" x="1350" y="360" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-57" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontSize=24;" value="View" vertex="1">
<mxGeometry height="30" width="60" x="1370" y="390" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-59" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«&lt;i&gt;Interface&lt;/i&gt;»&lt;br&gt;&lt;b&gt;GameView&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ displayBoard(board: ChessBoard): void&lt;br&gt;+ showMessage(msg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showError(errorMsg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showGameOver(status: GameStatus) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ setController(controller: ChessGame) : void&lt;/p&gt;" vertex="1">
<mxGeometry height="140" width="250" x="1540" y="475" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-60" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-49" style="endArrow=open;html=1;endSize=12;startArrow=none;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-54" value="">
<mxGeometry relative="1" x="-0.1581" y="3" as="geometry">
<Array as="points">
<mxPoint x="1786" y="150" />
<mxPoint x="1786" y="-75" />
</Array>
<mxPoint x="1480" y="150" as="sourcePoint" />
<mxPoint x="1440" y="336" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-63" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=open;endFill=0;fontSize=11;startSize=6;endSize=12;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-59">
<mxGeometry relative="1" x="-0.0639" as="geometry">
<Array as="points">
<mxPoint x="1425" y="295" />
<mxPoint x="1665" y="295" />
</Array>
<mxPoint x="2442" y="311" as="sourcePoint" />
<mxPoint x="1620" y="650" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-67" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ConsoleView&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- controller: ChessGame&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- scanner: Scanner&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ displayBoard(board: ChessBoard): void&lt;br&gt;+ showMessage(msg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showError(errorMsg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showGameOver(status: GameStatus) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ setController(controller: ChessGame) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&lt;/p&gt;" vertex="1">
<mxGeometry height="150" width="250" x="1390" y="735" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-68" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;SwingView&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- controller: ChessGame&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- frame: JFrame&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- boardPanel: JPanel&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;- squares: JButton[64]&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ displayBoard(board: ChessBoard): void&lt;br&gt;+ showMessage(msg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showError(errorMsg: String) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ showGameOver(status: GameStatus) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ setController(controller: ChessGame) : void&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&lt;/p&gt;" vertex="1">
<mxGeometry height="180" width="250" x="1690" y="735" as="geometry" />
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-69" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-67" style="html=1;verticalAlign=bottom;labelBackgroundColor=none;endArrow=open;endFill=0;dashed=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;" target="_r-HP5b758gAeptMtzsk-59" value="«implements»">
<mxGeometry relative="1" width="160" x="-0.0025" as="geometry">
<mxPoint x="1520" y="655" as="sourcePoint" />
<mxPoint x="1680" y="655" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_r-HP5b758gAeptMtzsk-70" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-68" style="html=1;verticalAlign=bottom;labelBackgroundColor=none;endArrow=open;endFill=0;dashed=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.665;entryY=0.981;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;entryPerimeter=0;" target="_r-HP5b758gAeptMtzsk-59" value="«implements»">
<mxGeometry relative="1" width="160" x="0.0723" as="geometry">
<Array as="points">
<mxPoint x="1790" y="735" />
<mxPoint x="1790" y="675" />
<mxPoint x="1706.3" y="675" />
</Array>
<mxPoint x="1740" y="785" as="sourcePoint" />
<mxPoint x="1823" y="665" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-0" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Final»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;«Record»&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Move&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&amp;nbsp;start: int&lt;br&gt;&amp;nbsp;end: int&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&amp;nbsp;isCapture: bool&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&amp;nbsp;isCastle: bool&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&amp;nbsp;isEnPassant: bool&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;&amp;nbsp;isCheck: bool&lt;/p&gt;&lt;div&gt;&amp;nbsp; movedPiece: Type&lt;/div&gt;&lt;div&gt;&amp;nbsp; promotedTo: Type&lt;/div&gt;&lt;div&gt;&amp;nbsp; capturedPieceColor: Color&lt;/div&gt;&lt;div&gt;&amp;nbsp; capturedPieceType: Type&lt;/div&gt;" vertex="1">
<mxGeometry height="200" width="190" x="1020" y="-230" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-2" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="1" vertex="1">
<mxGeometry height="30" width="60" x="1370" y="-130" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-3" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="*" vertex="1">
<mxGeometry height="30" width="60" x="1120" y="-70" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-4" parent="WIyWlLk6GJQsqaUBKTNV-1" style="shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;whiteSpace=wrap;fillColor=default;" value="" vertex="1">
<mxGeometry height="220" width="580" x="1350" y="-561" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-5" parent="WIyWlLk6GJQsqaUBKTNV-1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="Service" vertex="1">
<mxGeometry height="30" width="60" x="1360" y="-541" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-6" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;PGNWriter&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ write(List&amp;lt;Move&amp;gt;): void&lt;/p&gt;" vertex="1">
<mxGeometry height="60" width="160" x="1420" y="-431" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-7" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;PGNReader&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:4px;&quot;&gt;+ read(): List&amp;lt;Move&amp;gt;&lt;/p&gt;" vertex="1">
<mxGeometry height="60" width="160" x="1694" y="-431" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-8" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="oEUtffCDIGD-I46B6jyE-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;innerLoopWaypoints=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;" target="oEUtffCDIGD-I46B6jyE-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-11" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;libavoidRouting=1;" target="oEUtffCDIGD-I46B6jyE-6" value="Use">
<mxGeometry relative="1" width="160" as="geometry">
<Array as="points">
<mxPoint x="1480" y="-293" />
<mxPoint x="1500" y="-293" />
</Array>
<mxPoint x="1350" y="-320" as="sourcePoint" />
<mxPoint x="1510" y="-320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-12" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="_r-HP5b758gAeptMtzsk-47" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;libavoidRouting=1;" target="oEUtffCDIGD-I46B6jyE-7" value="Use">
<mxGeometry relative="1" width="160" x="0.3357" as="geometry">
<Array as="points">
<mxPoint x="1535" y="-293" />
<mxPoint x="1774" y="-293" />
</Array>
<mxPoint x="1750" y="-135" as="sourcePoint" />
<mxPoint x="1720" y="-290" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-13" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="oEUtffCDIGD-I46B6jyE-0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.996;entryY=0.707;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;startSize=5;endSize=12;" target="_r-HP5b758gAeptMtzsk-29">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-15" parent="WIyWlLk6GJQsqaUBKTNV-1" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" value="&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;«Enum»&lt;/p&gt;&lt;p style=&quot;margin: 4px 0px 0px; text-align: center; text-decoration: underline;&quot;&gt;Direction&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;div&gt;&amp;nbsp;NORTH&lt;/div&gt;&lt;div&gt;&amp;nbsp;SOUTH&lt;/div&gt;&lt;div&gt;&amp;nbsp;EAST&lt;/div&gt;&lt;div&gt;&amp;nbsp;WEST&lt;/div&gt;&lt;div&gt;&amp;nbsp;NORTH_EAST&lt;/div&gt;&lt;div&gt;&amp;nbsp;NORTH_WEST&lt;/div&gt;&lt;div&gt;&amp;nbsp;SOUTH_EAST&lt;/div&gt;&lt;div&gt;&amp;nbsp;SOUTH_WEST&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_NNE&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_ENE&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_ESE&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_SSE&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_SSW&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_WSW&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_WNW&lt;/div&gt;&lt;div&gt;&amp;nbsp;KNIGHT_NNW&lt;/div&gt;&lt;div&gt;&amp;nbsp;PAWN_DOUBLE_NORTH&lt;/div&gt;&lt;div&gt;&amp;nbsp;PAWN_DOUBLE_SOUTH&lt;/div&gt;&lt;div&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;div&gt;&amp;nbsp;- dx&lt;/div&gt;&lt;div&gt;&amp;nbsp;- dy&lt;/div&gt;&lt;div&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;div&gt;&amp;nbsp;+ getDx() : int&lt;/div&gt;&lt;div&gt;&amp;nbsp;+ getDy() : int&lt;/div&gt;&lt;div&gt;&amp;nbsp;+ getFlatOffset() : int&lt;/div&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt;" vertex="1">
<mxGeometry height="425" width="150" x="-290" y="-305" as="geometry" />
</mxCell>
<mxCell id="oEUtffCDIGD-I46B6jyE-16" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="oEUtffCDIGD-I46B6jyE-15" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;libavoidRouting=1;" target="_r-HP5b758gAeptMtzsk-0" value="Use">
<mxGeometry relative="1" width="160" x="0.2014" as="geometry">
<Array as="points">
<mxPoint x="-25" y="-92" />
<mxPoint x="-25" y="-131" />
<mxPoint x="315" y="-131" />
</Array>
<mxPoint x="-100" y="-130" as="sourcePoint" />
<mxPoint x="310" y="-79" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than draw.io -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" style="background: #ffffff; background-color: var(--ge-adaptive-bg, #ffffff); color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="2512px" height="1533px" viewBox="0 0 2512 1533" id="ge-svg-QP1ztADYlWT_awuG9Oml" content="&lt;mxfile host=&quot;app.diagrams.net&quot; scale=&quot;1&quot; border=&quot;20&quot;&gt;&#xA; &lt;diagram id=&quot;C5RBs43oDa-KdzZeNtuy&quot; name=&quot;Oldal-1&quot;&gt;&#xA; &lt;mxGraphModel dx=&quot;1857&quot; dy=&quot;1780&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;827&quot; pageHeight=&quot;1169&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&#xA; &lt;root&gt;&#xA; &lt;mxCell id=&quot;WIyWlLk6GJQsqaUBKTNV-0&quot; /&gt;&#xA; &lt;mxCell id=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-0&quot; /&gt;&#xA; &lt;mxCell id=&quot;_r-HP5b758gAeptMtzsk-38&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; style=&quot;shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;whiteSpace=wrap;fillColor=default;&quot; value=&quot;&quot; vertex=&quot;1&quot;&gt;&#xA; &lt;mxGeometry height=&quot;880&quot; width=&quot;1750&quot; x=&quot;-500&quot; y=&quot;-370&quot; as=&quot;geometry&quot; /&gt;&#xA; &lt;/mxCell&gt;&#xA; &lt;mxCell id=&quot;_r-HP5b758gAeptMtzsk-0&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; style=&quot;verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;&quot; value=&quot;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;«Abstract»&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Piece&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;hr size=&amp;quot;1&amp;quot; style=&amp;quot;border-style:solid;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;- pieceColor: Color&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;- movedBefore: boolean&amp;lt;/p&amp;gt;&amp;lt;hr size=&amp;quot;1&amp;quot; style=&amp;quot;border-style:solid;&amp;quot;&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ Piece(Color)&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ getMoveDomain() : Direction[]&amp;amp;nbsp;&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ getColor() : Color&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ getSymbol() : Char&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ getType() : Type&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-left:4px;&amp;quot;&amp;gt;+ hasMoved() : bool&amp;lt;/p&amp;gt;&quot; vertex=&quot;1&quot;&gt;&#xA; &lt;mxGeometry height=&quot;170&quot; width=&quot;260&quot; x=&quot;250&quot; y=&quot;-30&quot; as=&quot;geometry&quot; /&gt;&#xA; &lt;/mxCell&gt;&#xA; &lt;mxCell id=&quot;_r-HP5b758gAeptMtzsk-3&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; style=&quot;verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;&quot; value=&quot;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;«Final»&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Pawn&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;hr size=&amp;quot;1&amp;quot; style=&amp;quot;border-style:solid;&amp;quot;&amp;gt;&amp;amp;nbsp;+ getMoveDomain() : Direction[]&quot; vertex=&quot;1&quot;&gt;&#xA; &lt;mxGeometry height=&quot;70&quot; width=&quot;176&quot; x=&quot;-486&quot; y=&quot;390&quot; as=&quot;geometry&quot; /&gt;&#xA; &lt;/mxCell&gt;&#xA; &lt;mxCell id=&quot;_r-HP5b758gAeptMtzsk-4&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; style=&quot;verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;&quot; value=&quot;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;«Final»&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;margin:0px;margin-top:4px;text-align:center;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;King&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;hr size=&amp;quot;1&amp;quot; style=&amp;quot;border-style:solid;&amp;quot;&amp;gt;&amp;amp;nbsp;+ getMoveDomain() : Direction[]&quot; vertex=&quot;1&quot;&gt;&#xA; &lt;mxGeometry height=&quot;70&quot; width=&quot;176&quot; x=&quot;-176&quot; y=&quot;390&quot; as=&quot;geometry&quot; /&gt;&#xA; &lt;/mxCell&gt;&#xA; &lt;mxCell id=&quot;_r-HP5b758gAeptMtzsk-5&quot; parent=&quot;WIyWlLk6GJQsqaUBKTNV-1&quot; style=&quot;verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;&quoLine truncated

After

Width:  |  Height:  |  Size: 953 KiB

@@ -0,0 +1,6 @@
package com.gitea.lin.model;
public enum Color {
WHITE,
BLACK,
}
@@ -0,0 +1,53 @@
package com.gitea.lin.model;
public enum Direction {
// Orthogonal (Rook, Queen, King)
NORTH(0, -1),
SOUTH(0, 1),
EAST(1, 0),
WEST(-1, 0),
// Diagonal (Bishop, Queen, King, Pawn captures)
NORTH_EAST(1, -1),
NORTH_WEST(-1, -1),
SOUTH_EAST(1, 1),
SOUTH_WEST(-1, 1),
// Knight Jumps (L-shapes)
KNIGHT_NNE(1, -2),
KNIGHT_ENE(2, -1),
KNIGHT_ESE(2, 1),
KNIGHT_SSE(1, 2),
KNIGHT_SSW(-1, 2),
KNIGHT_WSW(-2, 1),
KNIGHT_WNW(-2, -1),
KNIGHT_NNW(-1, -2),
// Pawn Initial Double Push
PAWN_DOUBLE_NORTH(0, -2),
PAWN_DOUBLE_SOUTH(0, 2);
private final int dx;
private final int dy;
Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
public int getDx() {
return dx;
}
public int getDy() {
return dy;
}
/**
* Converts the 2D vector into a 1D array offset for Piece[64].
* (Assuming index 0 is top-left a8 and 63 is bottom-right h1)
*/
public int getFlatOffset() {
return dy * 8 + dx;
}
}
@@ -0,0 +1,24 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class Bishop extends Piece {
public Bishop(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
return new Direction[] {NORTH_EAST, NORTH_WEST, SOUTH_EAST, SOUTH_WEST};
}
@Override
public int getMaximumStep() { return 7; }
@Override
public char getSymbol() { return 'B'; }
@Override
public Type getType() { return Type.BISHOP; }
}
@@ -0,0 +1,33 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class King extends Piece {
public King(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
return new Direction[] {NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NORTH_WEST};
}
@Override
public int getMaximumStep() {
return 1;
}
@Override
public char getSymbol() {
return 'K';
}
@Override
public Type getType() {
return Type.KING;
}
}
@@ -0,0 +1,24 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class Knight extends Piece {
public Knight(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
return new Direction[] {KNIGHT_ENE, KNIGHT_ESE, KNIGHT_NNE, KNIGHT_NNW, KNIGHT_SSE, KNIGHT_SSW, KNIGHT_WNW, KNIGHT_WSW};
}
@Override
public int getMaximumStep() { return 2; }
@Override
public char getSymbol() { return 'N'; }
@Override
public Type getType() { return Type.KNIGHT; }
}
@@ -0,0 +1,44 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class Pawn extends Piece {
public Pawn(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
boolean isWhite = super.getColor() == Color.WHITE;
Direction forward = isWhite ? NORTH : SOUTH;
Direction forwardDouble = isWhite ? PAWN_DOUBLE_NORTH : PAWN_DOUBLE_SOUTH;
Direction hitLeft = isWhite ? NORTH_WEST : SOUTH_WEST;
Direction hitRight = isWhite ? NORTH_EAST : SOUTH_EAST;
if (super.hasMoved()) {
return new Direction[] {forward, hitLeft, hitRight};
}
return new Direction[] {forward, forwardDouble, hitLeft, hitRight};
}
@Override
public int getMaximumStep() {
return super.hasMoved() ? 1 : 2;
}
@Override
public char getSymbol() {
return 'P';
}
@Override
public Type getType() {
return Type.PAWN;
}
}
@@ -0,0 +1,27 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
public abstract class Piece {
private Color pieceColor;
private boolean movedBefore;
public Piece(Color c) {
this.pieceColor = c;
}
public abstract Direction[] getMoveDomain();
public abstract int getMaximumStep(); // TODO: Update UML
public abstract char getSymbol();
public abstract Type getType();
public Color getColor() {
return this.pieceColor;
}
public boolean hasMoved() {
return this.movedBefore;
}
}
@@ -0,0 +1,24 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class Queen extends Piece {
public Queen(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
return new Direction[] {NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NORTH_WEST};
}
@Override
public int getMaximumStep() { return 7; }
@Override
public char getSymbol() { return 'Q'; }
@Override
public Type getType() { return Type.QUEEN; }
}
@@ -0,0 +1,24 @@
package com.gitea.lin.model.Piece;
import com.gitea.lin.model.Color;
import com.gitea.lin.model.Direction;
import com.gitea.lin.model.Type;
import static com.gitea.lin.model.Direction.*;
public final class Rook extends Piece {
public Rook(Color c) {
super(c);
}
@Override
public Direction[] getMoveDomain() {
return new Direction[] {NORTH, EAST, SOUTH, WEST};
}
@Override
public int getMaximumStep() { return 7; }
@Override
public char getSymbol() { return 'R'; }
@Override
public Type getType() { return Type.ROOK; }
}
@@ -0,0 +1,10 @@
package com.gitea.lin.model;
public enum Type {
PAWN,
KING,
QUEEN,
ROOK,
BISHOP,
KNIGHT,
}