Compare commits
41 Commits
Menu_Featu
...
f0701fe9e7
Author | SHA1 | Date | |
---|---|---|---|
f0701fe9e7
|
|||
b462ae3c7e
|
|||
8ad2a1342a
|
|||
99007047eb
|
|||
|
d8b9430120 | ||
|
4f4d598eb6 | ||
|
2f065f4917 | ||
3e8d6d9557
|
|||
|
6c8d033629 | ||
|
3dfe314836 | ||
|
ca546e5ba6 | ||
|
6b01273580 | ||
625d607ef0
|
|||
|
14869f4a83 | ||
|
47b880e737 | ||
efd60b89e4
|
|||
bbd92bfa8b | |||
65227d12ab | |||
d2fbaa4af6
|
|||
|
2ae5de715d | ||
8d75c055c0 | |||
83eb22e627 | |||
30cd5c4af8 | |||
faa0e236b6 | |||
|
12a009b7db | ||
|
373c186075 | ||
|
9821f78c87 | ||
50b3312f49
|
|||
aa06318c07
|
|||
7695efa5d3
|
|||
c38f134254
|
|||
99c644bffb
|
|||
4602cbe187
|
|||
0a1f3d1e26
|
|||
4cf45f75bc
|
|||
4bf1447673
|
|||
27b684c550
|
|||
47b6a82be8
|
|||
af5b4ceb66
|
|||
36558c0c7c
|
|||
2d9d1d1eb3
|
@@ -8,3 +8,7 @@ trim_trailing_whitespace = true
|
||||
|
||||
[*.{cc,cpp,hpp,h}]
|
||||
insert_final_newline = true
|
||||
|
||||
[makefile]
|
||||
indent_size = 4
|
||||
indent_style = tab
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
.vscode/
|
||||
.idea/
|
||||
*.exe
|
||||
*.txt
|
||||
chess
|
188
.idea/editor.xml
generated
188
.idea/editor.xml
generated
@@ -1,103 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BackendCodeEditorSettings">
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
@@ -337,6 +246,97 @@
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexRemoved" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexRemoved" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexRemoved" />
|
||||
|
@@ -127,6 +127,54 @@ ChessPiecePosition ChessPiece::GetPosition() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all chess piece positions of the chess piece which are still protective for the king.
|
||||
* Any position between the attacker chess piece and the current chess piece is protective for the king.
|
||||
* The position is also protective for the king if the chess piece can beat the attacker chess piece.
|
||||
* @param chessboard A pointer to the chessboard.
|
||||
* @param positions A set of positions the chess piece can move next (also positions are not protective).
|
||||
* @return A set of chess piece positions which are still protective for the king.
|
||||
*/
|
||||
std::set<ChessPiecePosition> ChessPiece::GetProtectivePositions(Chessboard* chessboard, std::set<ChessPiecePosition> positions) {
|
||||
ChessPiece* chessPieceKing = chessboard->GetChessPieceKing(this->GetColor());
|
||||
std::set<ChessPiecePosition> protectivePositions;
|
||||
|
||||
for (ChessPiece* chessPiece : chessboard->GetChessPieces()) {
|
||||
if (chessPiece->GetColor() != this->GetColor()) {
|
||||
std::set<ChessPiecePosition> positionsStay = chessPiece->GetNextPositions(chessboard, {});
|
||||
std::set<ChessPiecePosition> positionsMove = chessPiece->GetNextPositions(chessboard, {this->GetPosition()});
|
||||
|
||||
if (positionsStay.count(chessPieceKing->GetPosition()) == 0 && positionsMove.count(chessPieceKing->GetPosition()) == 1) {
|
||||
|
||||
// the position is protective if the current chess piece can beat the attacker chess piece.
|
||||
if (positions.count(chessPiece->GetPosition()) == 1) {
|
||||
protectivePositions.insert(chessPiece->GetPosition());
|
||||
}
|
||||
|
||||
// every position between the current chess piece and the attacker chess piece is also protective.
|
||||
std::string step = ChessPiecePosition::GetStep(chessPiece->GetPosition(), chessPieceKing->GetPosition());
|
||||
|
||||
if (step.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChessPiecePosition currentPosition = chessPiece->GetPosition();
|
||||
ChessPiecePosition* nextPosition = ¤tPosition;
|
||||
|
||||
while (nextPosition = nextPosition->NextFromString(step)) {
|
||||
if (nextPosition->ToString() == this->GetPosition().ToString()) {
|
||||
break;
|
||||
} else if (positions.count(*nextPosition) == 1) {
|
||||
protectivePositions.insert(*nextPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return protectivePositions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of all positions along the rank.
|
||||
* @param chessboard A pointer to the chessboard.
|
||||
@@ -300,7 +348,7 @@ void ChessPiece::SetPosition(ChessPiecePosition position) {
|
||||
*/
|
||||
void ChessPiece::UpdateNextPositions(Chessboard* chessboard) {
|
||||
if (this->IsProtective(chessboard)) {
|
||||
this->SetNextPositions({});
|
||||
this->SetNextPositions(this->GetProtectivePositions(chessboard, this->GetNextPositions(chessboard)));
|
||||
} else {
|
||||
this->SetNextPositions(this->GetNextPositions(chessboard));
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ class ChessPiece {
|
||||
ChessPieceColor _color;
|
||||
std::vector<ChessPiecePosition> _positions;
|
||||
std::set<ChessPiecePosition> _positions_next;
|
||||
std::set<ChessPiecePosition> GetProtectivePositions(Chessboard* chessboard, std::set<ChessPiecePosition> positions);
|
||||
bool IsProtective(Chessboard* chessboard);
|
||||
|
||||
protected:
|
||||
char _char = '\0';
|
||||
@@ -46,7 +48,6 @@ class ChessPiece {
|
||||
bool IsKing();
|
||||
bool IsKnight();
|
||||
bool IsPawn();
|
||||
bool IsProtective(Chessboard* chessboard);
|
||||
bool IsQueen();
|
||||
bool IsRook();
|
||||
void SetPosition(ChessPiecePosition position);
|
||||
|
168
ChessPieces/ChessPieceMove.cpp
Normal file
168
ChessPieces/ChessPieceMove.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "../ChessPieces/ChessPieceMove.hpp"
|
||||
|
||||
/**
|
||||
* Creates a new move of a chess piece that uses the short algebraic notation.
|
||||
* @param move The move that uses the short algebraic notation.
|
||||
*/
|
||||
ChessPieceMove::ChessPieceMove(std::string move) {
|
||||
this->_move = this->Normalize(move);
|
||||
|
||||
if (this->IsValidShortNotation()) {
|
||||
this->ParseShortNotation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is a valid move that uses the short algebraic notation.
|
||||
* @return Status whether the move is a valid move that uses the short algebraic notation.
|
||||
*/
|
||||
bool ChessPieceMove::IsValidShortNotation(std::string move) {
|
||||
if (move.empty()) {
|
||||
return std::regex_match(this->_move, this->_notation);
|
||||
} else {
|
||||
return std::regex_match(move, this->_notation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the move which, if valid, can then be parsed.
|
||||
* @param move The move to be normalized.
|
||||
* @return The normalized move which, if valid, can then be parsed.
|
||||
*/
|
||||
std::string ChessPieceMove::Normalize(std::string move) {
|
||||
std::replace(move.begin(), move.end(), 'O', '0'); // castling: portable game notation to algebraic notation
|
||||
std::replace(move.begin(), move.end(), 'S', 'N'); // german notation to english notation (knight)
|
||||
std::replace(move.begin(), move.end(), 'L', 'B'); // german notation to english notation (bishop)
|
||||
std::replace(move.begin(), move.end(), 'T', 'R'); // german notation to english notation (queen)
|
||||
return move;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a move that uses the short algebraic notation.
|
||||
*/
|
||||
void ChessPieceMove::ParseShortNotation() {
|
||||
std::smatch parts;
|
||||
std::regex_search(this->_move, parts, this->_notation);
|
||||
this->_chessPiece = parts[1].str();
|
||||
this->_fromPositionFile = parts[2].str();
|
||||
this->_fromPositionRank = parts[3].str();
|
||||
this->_capture = parts[4].str();
|
||||
this->_toPositionFile = parts[5].str();
|
||||
this->_toPositionRank = parts[6].str();
|
||||
this->_promotion = parts[7].str();
|
||||
this->_castling = parts[8].str();
|
||||
this->_draw = parts[9].str();
|
||||
this->_additional = parts[10].str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chess piece char of the move.
|
||||
* @return The chess piece char of the move.
|
||||
*/
|
||||
char ChessPieceMove::GetChessPieceChar() {
|
||||
return this->_chessPiece.empty() ? 'P' : this->_chessPiece[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file part of the source position.
|
||||
* @return The file part of the source position.
|
||||
*/
|
||||
char ChessPieceMove::GetFromPositionFile() {
|
||||
return this->_fromPositionFile.empty() ? '\0' : this->_fromPositionFile[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank part of the source position.
|
||||
* @return The rank part of the source position.
|
||||
*/
|
||||
int ChessPieceMove::GetFromPositionRank() {
|
||||
return this->_fromPositionRank.empty() ? 0 : stoi(this->_fromPositionRank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chess piece character of the promotion.
|
||||
* @return The chess piece character of the promotion.
|
||||
*/
|
||||
char ChessPieceMove::GetPromotionChessPieceChar() {
|
||||
return this->_promotion.empty() ? '\0' : this->_promotion[this->_promotion.length() - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file part of the target position.
|
||||
* @return The file part of the target position.
|
||||
*/
|
||||
char ChessPieceMove::GetToPositionFile() {
|
||||
return this->_toPositionFile.empty() ? '\0' : this->_toPositionFile[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank part of the target position.
|
||||
* @return The rank part of the target position.
|
||||
*/
|
||||
int ChessPieceMove::GetToPositionRank() {
|
||||
return this->_toPositionRank.empty() ? 0 : stoi(this->_toPositionRank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is a move with capture.
|
||||
* @return Status whether the move is a move with capture.
|
||||
*/
|
||||
bool ChessPieceMove::IsCapture() {
|
||||
return this->_capture == "x" ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move results in a check.
|
||||
* @return Status whether the move results in a check.
|
||||
*/
|
||||
bool ChessPieceMove::IsCheck() {
|
||||
return this->_additional == "+";
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move results in a checkmate.
|
||||
* @return Status whether the move results in a checkmate.
|
||||
*/
|
||||
bool ChessPieceMove::IsCheckmate() {
|
||||
return this->_additional == "++" || this->_additional == "#";
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is a offer for a draw.
|
||||
* @return Status whether the move is a offer for a draw.
|
||||
*/
|
||||
bool ChessPieceMove::IsDrawOffer() {
|
||||
return this->_draw == "(=)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is an "en passant" by pawn.
|
||||
* @return Status whether the move is an "en passant" by pawn.
|
||||
*/
|
||||
bool ChessPieceMove::IsEnPassant() {
|
||||
return this->_additional == "e.p.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is the long castling (castling queenside).
|
||||
* @return Status whether the move is the long castling (castling queenside).
|
||||
*/
|
||||
bool ChessPieceMove::IsLongCastling() {
|
||||
return this->_castling == "0-0-0";
|
||||
}
|
||||
|
||||
/**
|
||||
* Status whether the move is the short castling (castling kingside).
|
||||
* @return Status whether the move is the short castling (castling kingside).
|
||||
*/
|
||||
bool ChessPieceMove::IsShortCastling() {
|
||||
return this->_castling == "0-0";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the move of the chess piece as string value.
|
||||
* @return The move of the chess piece as string value.
|
||||
*/
|
||||
std::string ChessPieceMove::ToString() {
|
||||
return (this->IsValidShortNotation()) ? this->_move : "";
|
||||
}
|
42
ChessPieces/ChessPieceMove.hpp
Normal file
42
ChessPieces/ChessPieceMove.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef ChessPieceMove_H
|
||||
#define ChessPieceMove_H
|
||||
|
||||
#include <regex>
|
||||
|
||||
class ChessPieceMove {
|
||||
private:
|
||||
std::string _chessPiece;
|
||||
std::string _fromPositionFile;
|
||||
std::string _fromPositionRank;
|
||||
std::string _capture;
|
||||
std::string _toPositionFile;
|
||||
std::string _toPositionRank;
|
||||
std::string _promotion;
|
||||
std::string _castling;
|
||||
std::string _draw;
|
||||
std::string _additional;
|
||||
std::string _move;
|
||||
const std::regex _notation = std::regex("^(?:([RNBQKP]?)([a-h]?)([1-8]?)(x?)([a-h])([1-8])((?:[=])?[QRBN])?|(0-0(?:-0)?)|(\\(=\\)))([+#!?]| e.p.)*$");
|
||||
std::string Normalize(std::string move);
|
||||
void ParseShortNotation();
|
||||
|
||||
public:
|
||||
ChessPieceMove(std::string move);
|
||||
bool IsValidShortNotation(std::string move = "");
|
||||
char GetChessPieceChar();
|
||||
char GetFromPositionFile();
|
||||
int GetFromPositionRank();
|
||||
bool IsCapture();
|
||||
char GetToPositionFile();
|
||||
int GetToPositionRank();
|
||||
char GetPromotionChessPieceChar();
|
||||
bool IsShortCastling();
|
||||
bool IsLongCastling();
|
||||
bool IsDrawOffer();
|
||||
bool IsCheck();
|
||||
bool IsCheckmate();
|
||||
bool IsEnPassant();
|
||||
std::string ToString();
|
||||
};
|
||||
|
||||
#endif
|
@@ -56,18 +56,18 @@ std::string ChessPiecePosition::GetDifference(ChessPiecePosition fromPosition, C
|
||||
} else {
|
||||
std::string difference;
|
||||
|
||||
if (toPosition.GetFile() < fromPosition.GetFile()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::to_string(fromPosition.GetFile() - toPosition.GetFile()));
|
||||
} else if (toPosition.GetFile() > fromPosition.GetFile()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::to_string(toPosition.GetFile() - fromPosition.GetFile()));
|
||||
}
|
||||
|
||||
if (toPosition.GetRank() < fromPosition.GetRank()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_BOTTOM) + std::to_string(fromPosition.GetRank() - toPosition.GetRank()));
|
||||
} else if (toPosition.GetRank() > fromPosition.GetRank()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_TOP) + std::to_string(toPosition.GetRank() - fromPosition.GetRank()));
|
||||
}
|
||||
|
||||
if (toPosition.GetFile() < fromPosition.GetFile()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_LEFT) + std::to_string(fromPosition.GetFile() - toPosition.GetFile()));
|
||||
} else if (toPosition.GetFile() > fromPosition.GetFile()) {
|
||||
difference.append(std::string(1, ChessPiecePosition::_MOVE_RIGHT) + std::to_string(toPosition.GetFile() - fromPosition.GetFile()));
|
||||
}
|
||||
|
||||
return difference;
|
||||
}
|
||||
}
|
||||
|
@@ -34,10 +34,38 @@ std::set<ChessPiecePosition> King::GetNextPositions(Chessboard* chessboard, std:
|
||||
ChessPieceColor opponentColor = (this->GetColor() == ChessPieceColor::Black) ? ChessPieceColor::White : ChessPieceColor::Black;
|
||||
|
||||
if (chessboard->IsPositionUnderAttack(*nextPosition, opponentColor) == false) {
|
||||
bool isUnderAttackAfterMove = false;
|
||||
|
||||
// Positions are ignored which are still under attack after the king has moved.
|
||||
// There are fields under attack which are in the shadow of the king.
|
||||
for (ChessPiece* chessPiece : chessboard->GetChessPieces()) {
|
||||
if (chessPiece && chessPiece->GetColor() != this->GetColor()) {
|
||||
if (chessPiece->GetNextPositions().count(this->GetPosition()) == 1) {
|
||||
if (chessPiece->IsPawn()) continue; // is checked by under attack
|
||||
|
||||
if (chessPiece->GetNextPositions(chessboard, {this->GetPosition(), *nextPosition}).count(*nextPosition) == 1) {
|
||||
isUnderAttackAfterMove = true;
|
||||
break;
|
||||
}
|
||||
} else if (chessPiece->IsKing()) {
|
||||
for (std::string nextMove : {"T1", "T1L1", "T1R1", "R1", "L1", "B1", "B1L1", "B1R1"}) {
|
||||
ChessPiecePosition* nextPositionKing = chessPiece->GetPosition().NextFromString(nextMove);
|
||||
|
||||
if (nextPositionKing && *nextPosition == *nextPositionKing) {
|
||||
isUnderAttackAfterMove = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isUnderAttackAfterMove == false) {
|
||||
positions.insert(*nextPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
@@ -21,22 +21,28 @@ std::set<ChessPiecePosition> Pawn::GetNextPositions(Chessboard* chessboard, std:
|
||||
std::set<ChessPiecePosition> positions;
|
||||
ChessPiecePosition currentPosition = this->GetPosition();
|
||||
ChessPiecePosition* nextPosition = ¤tPosition;
|
||||
std::vector<std::string> nextDiagonalPositions;
|
||||
std::string moveDifferenceOpponent;
|
||||
|
||||
if (this->GetColor() == ChessPieceColor::Black) {
|
||||
if (this->GetColor() == ChessPieceColor::White) {
|
||||
nextDiagonalPositions = {"T1L1", "T1R1"};
|
||||
moveDifferenceOpponent = "B2";
|
||||
} else {
|
||||
nextDiagonalPositions = {"B1L1", "B1R1"};
|
||||
moveDifferenceOpponent = "T2";
|
||||
}
|
||||
|
||||
std::string stepVertical = nextDiagonalPositions[0].substr(0, 2);
|
||||
|
||||
// 3.7.1. The pawn may move forward to the square immediately in front of it on the same file, provided that this square is unoccupied.
|
||||
// 3.7.2. On its first move the pawn may move as in 3.7.1 or alternatively it may advance two squares along the same file, provided that both squares are unoccupied.
|
||||
for (int move = 1; move <= 2; move++) {
|
||||
nextPosition = nextPosition->NextBottom();
|
||||
|
||||
if (nextPosition) {
|
||||
if (nextPosition = nextPosition->NextFromString(stepVertical)) {
|
||||
if (chessboard->IsEmptyField(nextPosition) == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (move == 1) {
|
||||
positions.insert(*nextPosition);
|
||||
} else if (move == 2 && this->IsFirstMove()) {
|
||||
if (move == 1 || (move == 2 && this->IsFirstMove())) {
|
||||
positions.insert(*nextPosition);
|
||||
}
|
||||
} else {
|
||||
@@ -45,9 +51,9 @@ std::set<ChessPiecePosition> Pawn::GetNextPositions(Chessboard* chessboard, std:
|
||||
}
|
||||
|
||||
// 3.7.3. the pawn may move to a square occupied by an opponent's piece diagonally in front of it on an adjacent file, capturing that piece.
|
||||
for (std::string move : {"B1L1", "B1R1"}) {
|
||||
for (std::string moveDiagonal : nextDiagonalPositions) {
|
||||
nextPosition = ¤tPosition;
|
||||
nextPosition = nextPosition->NextFromString(move);
|
||||
nextPosition = nextPosition->NextFromString(moveDiagonal);
|
||||
|
||||
if (nextPosition && chessboard->IsEmptyField(nextPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(nextPosition);
|
||||
@@ -62,107 +68,23 @@ std::set<ChessPiecePosition> Pawn::GetNextPositions(Chessboard* chessboard, std:
|
||||
// in one move from its original square may capture this opponent's pawn as though the latter had been moved only one square.
|
||||
// 3.7.3.2. This capture is only legal on the move following this advance and is called an "en passant" capture.
|
||||
if (chessboard->GetCountMoves() > 0) {
|
||||
std::pair<ChessPiecePosition, ChessPiecePosition> lastMove = chessboard->GetLastMove();
|
||||
std::string moveDifference = ChessPiecePosition::GetDifference(lastMove.first, lastMove.second);
|
||||
ChessPiecePosition* leftPosition = currentPosition.NextLeft();
|
||||
ChessPiecePosition* rightPosition = currentPosition.NextRight();
|
||||
std::pair<ChessPiecePosition, ChessPiecePosition> lastMovePositions = chessboard->GetLastMovePositions();
|
||||
std::string moveDifference = ChessPiecePosition::GetDifference(lastMovePositions.first, lastMovePositions.second);
|
||||
|
||||
if (leftPosition && chessboard->IsEmptyField(leftPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(leftPosition);
|
||||
|
||||
if (chessPiece->GetColor() != this->GetColor() && chessPiece->IsPawn()) {
|
||||
if (chessPiece->GetNumberOfMoves() == 1 && moveDifference == "T2" && chessPiece->GetPosition() == lastMove.second) {
|
||||
ChessPiecePosition* bottomLeftPosition = currentPosition.NextFromString("B1L1");
|
||||
|
||||
if (bottomLeftPosition && chessboard->IsEmptyField(bottomLeftPosition)) {
|
||||
positions.insert(*bottomLeftPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rightPosition && chessboard->IsEmptyField(rightPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(rightPosition);
|
||||
|
||||
if (chessPiece->GetColor() != this->GetColor() && chessPiece->IsPawn()) {
|
||||
if (chessPiece->GetNumberOfMoves() == 1 && moveDifference == "T2" && chessPiece->GetPosition() == lastMove.second) {
|
||||
ChessPiecePosition* bottomRightPosition = currentPosition.NextFromString("B1R1");
|
||||
|
||||
if (bottomRightPosition && chessboard->IsEmptyField(bottomRightPosition)) {
|
||||
positions.insert(*bottomRightPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this->GetColor() == ChessPieceColor::White) {
|
||||
|
||||
// 3.7.1. The pawn may move forward to the square immediately in front of it on the same file, provided that this square is unoccupied.
|
||||
// 3.7.2. On its first move the pawn may move as in 3.7.1 or alternatively it may advance two squares along the same file, provided that both squares are unoccupied.
|
||||
for (int move = 1; move <= 2; move++) {
|
||||
nextPosition = nextPosition->NextTop();
|
||||
|
||||
if (nextPosition) {
|
||||
if (chessboard->IsEmptyField(nextPosition) == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (move == 1) {
|
||||
positions.insert(*nextPosition);
|
||||
} else if (move == 2 && this->IsFirstMove()) {
|
||||
positions.insert(*nextPosition);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3.7.3. the pawn may move to a square occupied by an opponent's piece diagonally in front of it on an adjacent file, capturing that piece.
|
||||
for (std::string move : {"T1L1", "T1R1"}) {
|
||||
for (std::string nextDiagonalPosition : nextDiagonalPositions) {
|
||||
nextPosition = ¤tPosition;
|
||||
nextPosition = nextPosition->NextFromString(move);
|
||||
std::string stepDiagonal = nextDiagonalPosition.substr(2, 2);
|
||||
nextPosition = nextPosition->NextFromString(stepDiagonal);
|
||||
|
||||
if (nextPosition && chessboard->IsEmptyField(nextPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(nextPosition);
|
||||
|
||||
if (chessPiece->GetColor() != this->GetColor()) {
|
||||
positions.insert(*nextPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chessPiece->IsPawn() && chessPiece->GetColor() != this->GetColor()) {
|
||||
if (chessPiece->GetNumberOfMoves() == 1 && moveDifference == moveDifferenceOpponent && chessPiece->GetPosition() == lastMovePositions.second) {
|
||||
ChessPiecePosition* diagonalPosition = currentPosition.NextFromString(nextDiagonalPosition);
|
||||
|
||||
// 3.7.3.1. A pawn occupying a square on the same rank as and on an adjacent file to an opponent's pawn which has just advanced two squares
|
||||
// in one move from its original square may capture this opponent's pawn as though the latter had been moved only one square.
|
||||
// 3.7.3.2. This capture is only legal on the move following this advance and is called an "en passant" capture.
|
||||
if (chessboard->GetCountMoves() > 0) {
|
||||
std::pair<ChessPiecePosition, ChessPiecePosition> lastMove = chessboard->GetLastMove();
|
||||
std::string moveDifference = ChessPiecePosition::GetDifference(lastMove.first, lastMove.second);
|
||||
ChessPiecePosition* leftPosition = currentPosition.NextLeft();
|
||||
ChessPiecePosition* rightPosition = currentPosition.NextRight();
|
||||
|
||||
if (leftPosition && chessboard->IsEmptyField(leftPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(leftPosition);
|
||||
|
||||
if (chessPiece->GetColor() != this->GetColor() && chessPiece->IsPawn()) {
|
||||
if (chessPiece->GetNumberOfMoves() == 1 && moveDifference == "B2" && chessPiece->GetPosition() == lastMove.second) {
|
||||
ChessPiecePosition* topLeftPosition = currentPosition.NextFromString("T1L1");
|
||||
|
||||
if (topLeftPosition && chessboard->IsEmptyField(topLeftPosition)) {
|
||||
positions.insert(*topLeftPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rightPosition && chessboard->IsEmptyField(rightPosition) == false) {
|
||||
ChessPiece* chessPiece = chessboard->GetChessPiece(rightPosition);
|
||||
|
||||
if (chessPiece->GetColor() != this->GetColor() && chessPiece->IsPawn()) {
|
||||
if (chessPiece->GetNumberOfMoves() == 1 && moveDifference == "B2" && chessPiece->GetPosition() == lastMove.second) {
|
||||
ChessPiecePosition* topRightPosition = currentPosition.NextFromString("T1R1");
|
||||
|
||||
if (topRightPosition && chessboard->IsEmptyField(topRightPosition)) {
|
||||
positions.insert(*topRightPosition);
|
||||
if (diagonalPosition && chessboard->IsEmptyField(diagonalPosition)) {
|
||||
positions.insert(*diagonalPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by hamac on 18.12.2024.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "ChessUtils.h"
|
||||
|
||||
std::vector<std::string> ChessUtils::split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
while (std::getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
//a4
|
||||
std::pair<int, int> ChessUtils::convertPosition(const std::string &pos) {
|
||||
int y = pos[pos.size()-2] - 'a';
|
||||
int x = ChessUtils::fileConvertion.find((pos[pos.size()-1] - '0')-1)->second;
|
||||
return std::make_pair(x, y);
|
||||
}
|
34
ChessUtils.h
34
ChessUtils.h
@@ -1,34 +0,0 @@
|
||||
//
|
||||
// Created by hamac on 20.12.2024.
|
||||
//
|
||||
|
||||
#ifndef CHESSUTILS_H
|
||||
#define CHESSUTILS_H
|
||||
|
||||
//
|
||||
// Created by hamac on 18.12.2024.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class ChessUtils {
|
||||
public:
|
||||
inline static const std::unordered_map<int, int> fileConvertion = {
|
||||
{0, 7},
|
||||
{1, 6},
|
||||
{2, 5},
|
||||
{3, 4},
|
||||
{4, 3},
|
||||
{5, 2},
|
||||
{6, 1},
|
||||
{7, 0}
|
||||
};
|
||||
static std::vector<std::string> split(const std::string &s, char delim);
|
||||
|
||||
static std::pair<int, int> convertPosition(const std::string &pos);
|
||||
};
|
||||
|
||||
#endif //CHESSUTILS_H
|
1012
Chessboard.cpp
1012
Chessboard.cpp
File diff suppressed because it is too large
Load Diff
133
Chessboard.h
133
Chessboard.h
@@ -1,133 +0,0 @@
|
||||
//
|
||||
// Created by hamac on 20.12.2024.
|
||||
//
|
||||
|
||||
#ifndef CHESSBOARD_H
|
||||
#define CHESSBOARD_H
|
||||
|
||||
#include "Chesspiece.h"
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class Chessboard {
|
||||
private:
|
||||
/* Constants */
|
||||
// Chars to display board
|
||||
// Corners
|
||||
const std::string topLeft = "┌";
|
||||
const std::string topRight = "┐";
|
||||
const std::string bottomLeft = "└";
|
||||
const std::string bottomRight = "┘";
|
||||
|
||||
// Line chars
|
||||
const std::string horizontal = "─";
|
||||
const std::string vertical = "│";
|
||||
const std::string topIntersection = "┬";
|
||||
const std::string bottomIntersection = "┴";
|
||||
const std::string middleIntersection = "┼";
|
||||
|
||||
// White pieces
|
||||
const std::string whiteSquare = "□";
|
||||
const std::string whiteKing = "♔";
|
||||
const std::string whiteQueen = "♕";
|
||||
const std::string whiteRook = "♖";
|
||||
const std::string whiteBischop = "♗";
|
||||
const std::string whiteKnight = "♘";
|
||||
const std::string whitePawn = "♙";
|
||||
|
||||
// Black pieces
|
||||
const std::string blackSquare = "■";
|
||||
const std::string blackKing = "♚";
|
||||
const std::string blackQueen = "♛";
|
||||
const std::string blackRook = "♜";
|
||||
const std::string blackBischop = "♝";
|
||||
const std::string blackKnight = "♞";
|
||||
const std::string blackPawn = "♟";
|
||||
|
||||
/* class fields */
|
||||
std::vector<std::vector<char>> currentBoard;
|
||||
|
||||
std::unordered_map<char, std::vector<std::unique_ptr<Chesspiece>>> playingPieces;
|
||||
|
||||
// Starting formatting
|
||||
std::vector<std::vector<char>> startBoard = {
|
||||
{'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'},
|
||||
{'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'},
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
|
||||
{'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'},
|
||||
{'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'},
|
||||
};
|
||||
|
||||
// ToDo: Mathematisch sicherlich weg rationalisierbar
|
||||
std::vector<std::vector<char>> emptyBoard = {
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'},
|
||||
{'w', 'x', 'w', 'x' ,'w', 'x', 'w', 'x'},
|
||||
{'x', 'w', 'x', 'w', 'x', 'w', 'x', 'w'}
|
||||
};
|
||||
|
||||
// Saves turn order; true = white and false = black
|
||||
bool turnOrder = true;
|
||||
|
||||
// ToDo: Max Size definieren?
|
||||
std::queue<std::string> queue;
|
||||
|
||||
/* methods */
|
||||
// Method returns unicode for chess icon depending on the identifier
|
||||
std::string getChessIcon(char identifier);
|
||||
|
||||
void generateTopLine();
|
||||
|
||||
void generatePlayingField(const std::vector<std::vector<char>>& chessboard);
|
||||
|
||||
void generateBottomLine();
|
||||
|
||||
public:
|
||||
/* fields */
|
||||
std::string display;
|
||||
int boardSize = 8;
|
||||
|
||||
/* methods */
|
||||
bool getTurnOrder();
|
||||
void setTurnOrder(bool turnOrder);
|
||||
|
||||
std::vector<std::vector<char>> getBoard();
|
||||
void setBoard(std::vector<std::vector<char>> board);
|
||||
|
||||
std::vector<std::vector<char>> getStartBoard();
|
||||
|
||||
std::vector<std::vector<char>> getEmptyBoard();
|
||||
|
||||
void draw ();
|
||||
|
||||
void draw (const std::vector<std::vector<char>>& chessboard);
|
||||
|
||||
void init();
|
||||
|
||||
void initPieces();
|
||||
|
||||
void move();
|
||||
|
||||
char getCorrectPiece(char pieceIdentifier);
|
||||
|
||||
//
|
||||
void move(std::string move);
|
||||
|
||||
// This method saves the current board state
|
||||
void saveBoard();
|
||||
|
||||
// This method loads a save state
|
||||
void loadBoard(std::string filepath);
|
||||
};
|
||||
|
||||
|
||||
#endif //CHESSBOARD_H
|
File diff suppressed because it is too large
Load Diff
@@ -9,95 +9,81 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include "../Player/Player.hpp"
|
||||
#include "../ChessPieces/ChessPieceColor.hpp"
|
||||
#include "../ChessPieces/ChessPieceMove.hpp"
|
||||
#include "../ChessPieces/ChessPiecePosition.hpp"
|
||||
|
||||
class ChessPiece;
|
||||
|
||||
class Chessboard {
|
||||
private:
|
||||
inline static const std::string save_path = "chessgames/save_files/";
|
||||
|
||||
Player* winner = nullptr;
|
||||
std::string currentSaveFilename;
|
||||
|
||||
// false, false => Laufend
|
||||
// true, false => black win
|
||||
// false, true => white win
|
||||
// true, true => Draw/Stalmate
|
||||
std::pair<bool, bool> game_status = std::make_pair(false, false);
|
||||
|
||||
std::vector<ChessPieceMove> _historyMoves;
|
||||
std::vector<std::pair<ChessPiecePosition, ChessPiecePosition>> _historyPositions;
|
||||
std::map<ChessPiecePosition, ChessPiece*> chessboard;
|
||||
std::vector<std::pair<ChessPiecePosition, ChessPiecePosition>> history;
|
||||
std::pair<Player*, Player*> players;
|
||||
std::pair<bool, bool> draw = std::make_pair(false, false);;
|
||||
Player* currentPlayer;
|
||||
void RemoveChessPiece(ChessPiecePosition position);
|
||||
|
||||
public:
|
||||
struct Board_ChessPiece {
|
||||
int color;
|
||||
char type;
|
||||
std::pair<char, int> position;
|
||||
|
||||
Board_ChessPiece(const int& c, const char& t, std::pair<char,int> p) : color(c), type(t), position(p) {}
|
||||
|
||||
bool operator<(const Board_ChessPiece& other) const {
|
||||
if (position != other.position) {
|
||||
return position < other.position;
|
||||
}
|
||||
if (color != other.color) {
|
||||
return color < other.color;
|
||||
}
|
||||
return type < other.type;
|
||||
}
|
||||
};
|
||||
inline static const std::set<Board_ChessPiece> defaultBoard = {
|
||||
{0, 'P', {'A', 7}},
|
||||
{0, 'P', {'B', 7}},
|
||||
{0, 'P', {'C', 7}},
|
||||
{0, 'P', {'D', 7}},
|
||||
{0, 'P', {'E', 7}},
|
||||
{0, 'P', {'F', 7}},
|
||||
{0, 'P', {'G', 7}},
|
||||
{0, 'P', {'H', 7}},
|
||||
{0, 'R', {'A', 8}},
|
||||
{0, 'K', {'B', 8}},
|
||||
{0, 'B', {'C', 8}},
|
||||
{0, 'Q', {'D', 8}},
|
||||
{0, 'K', {'E', 8}},
|
||||
{0, 'B', {'F', 8}},
|
||||
{0, 'K', {'G', 8}},
|
||||
{0, 'R', {'H', 8}},
|
||||
|
||||
{1, 'P', {'A', 2}},
|
||||
{1, 'P', {'B', 2}},
|
||||
{1, 'P', {'C', 2}},
|
||||
{1, 'P', {'D', 2}},
|
||||
{1, 'P', {'E', 2}},
|
||||
{1, 'P', {'F', 2}},
|
||||
{1, 'P', {'G', 2}},
|
||||
{1, 'P', {'H', 2}},
|
||||
{1, 'R', {'A', 1}},
|
||||
{1, 'N', {'B', 1}},
|
||||
{1, 'B', {'C', 1}},
|
||||
{1, 'Q', {'D', 1}},
|
||||
{1, 'K', {'E', 1}},
|
||||
{1, 'B', {'F', 1}},
|
||||
{1, 'K', {'G', 1}},
|
||||
{1, 'R', {'H', 1}}
|
||||
};
|
||||
~Chessboard();
|
||||
void InitializeStartBoard();
|
||||
void InitializeBoard(std::set<Board_ChessPiece> board);
|
||||
//void SetChessPiece(std::unique_ptr<ChessPiece> piece);
|
||||
std::vector<ChessPieceMove> GetHistoryMoves();
|
||||
std::vector<std::pair<ChessPiecePosition, ChessPiecePosition>> GetHistoryPositions();
|
||||
std::string GetTodaysDate(std::string format);
|
||||
void SetStartingPosition();
|
||||
void SetChessPiece(ChessPiece* chesspiece);
|
||||
bool IsDraw();
|
||||
bool IsEmptyField(ChessPiecePosition* position);
|
||||
ChessPiece* GetChessPiece(ChessPiecePosition* position);
|
||||
std::vector<ChessPiece*> GetChessPieces();
|
||||
void UpdateChessPieces();
|
||||
void MoveChessPiece(std::string move);
|
||||
std::string MoveCastling(ChessPieceColor color, bool shortCastling);
|
||||
std::string MoveChessPiece(std::string move);
|
||||
void SetToHistory(ChessPieceMove move);
|
||||
void SetToHistory(ChessPiecePosition fromPosition, ChessPiecePosition toPosition);
|
||||
int GetCountMoves();
|
||||
std::pair<ChessPiecePosition, ChessPiecePosition> GetLastMove();
|
||||
bool HasMoves();
|
||||
std::pair<ChessPiecePosition, ChessPiecePosition> GetLastMovePositions();
|
||||
bool IsCheckmate();
|
||||
bool IsCheck();
|
||||
bool IsInCheck();
|
||||
bool IsStalemate();
|
||||
bool IsPositionUnderAttack(ChessPiecePosition position, ChessPieceColor color);
|
||||
Player* GetCurrentPlayer();
|
||||
Player* GetOpponentPlayer();
|
||||
void SetPlayersRdm(Player* playerA, Player* playerB);
|
||||
void SetPlayers(Player* playerA, Player* playerB);
|
||||
void SwitchCurrentPlayer();
|
||||
Player* GetPlayer(ChessPieceColor color);
|
||||
ChessPiece* GetChessPieceKing(ChessPieceColor color);
|
||||
std::string ImportFilePGN(std::string filePath);
|
||||
bool ExportFilePGN(std::string filePath);
|
||||
void SetWinner(Player* winner);
|
||||
std::string GeneratePGNContent(std::string today, std::string player1, std::string player2, std::string round);
|
||||
std::string GenerateMoveList();
|
||||
std::pair<bool, bool> GetGameState();
|
||||
void SetGameState(std::pair<bool, bool> gameState);
|
||||
std::string GetPGNResult();
|
||||
std::string GetRound(const std::string& folderPath, const std::string& baseFileName);
|
||||
std::string GetCurrentSaveFilename();
|
||||
void SetCurrentSaveFilename(std::string currentSaveFileName);
|
||||
std::string GenerateExportFilePath(std::string& filePath);
|
||||
std::string GetWinner();
|
||||
bool IsFinished();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -1,317 +0,0 @@
|
||||
#include "../Chessboard/ChessboardVisualizerGraphic.hpp"
|
||||
#include "../ChessPieces/ChessPiecePosition.hpp"
|
||||
#include "../Visualizer/HistorieVisualizer.hpp"
|
||||
#include "../Visualizer/BaseVisualizer.hpp"
|
||||
|
||||
/*void ChessboardVisualizerGraphic::SetConsoleColor(Colors foreground, Colors background) {
|
||||
const std::string SEQ_FOREGROUND = "\x1b[3";
|
||||
const std::string SEQ_FOREGROUND_LIGHT = "\x1b[9";
|
||||
const std::string SEQ_BACKGROUND = "\x1b[4";
|
||||
const std::string SEQ_BACKGROUND_LIGHT = "\x1b[10";
|
||||
|
||||
// set foreground color
|
||||
switch (foreground) {
|
||||
case BLACK:
|
||||
case RED:
|
||||
case GREEN:
|
||||
case YELLOW:
|
||||
case BLUE:
|
||||
case MAGENTA:
|
||||
case CYAN:
|
||||
case WHITE:
|
||||
std::cout << SEQ_FOREGROUND << foreground << "m";
|
||||
break;
|
||||
case LIGHT_BLACK:
|
||||
case LIGHT_RED:
|
||||
case LIGHT_GREEN:
|
||||
case LIGHT_YELLOW:
|
||||
case LIGHT_BLUE:
|
||||
case LIGHT_MAGENTA:
|
||||
case LIGHT_CYAN:
|
||||
case LIGHT_WHITE:
|
||||
std::cout << SEQ_FOREGROUND_LIGHT << foreground << "m";
|
||||
break;
|
||||
case DEFAULT:
|
||||
default:
|
||||
std::cout << SEQ_FOREGROUND << foreground << "m";
|
||||
break;
|
||||
}
|
||||
|
||||
// set background color
|
||||
switch (background) {
|
||||
case BLACK:
|
||||
case RED:
|
||||
case GREEN:
|
||||
case YELLOW:
|
||||
case BLUE:
|
||||
case MAGENTA:
|
||||
case CYAN:
|
||||
case WHITE:
|
||||
std::cout << SEQ_BACKGROUND << background << "m";
|
||||
break;
|
||||
case LIGHT_BLACK:
|
||||
case LIGHT_RED:
|
||||
case LIGHT_GREEN:
|
||||
case LIGHT_YELLOW:
|
||||
case LIGHT_BLUE:
|
||||
case LIGHT_MAGENTA:
|
||||
case LIGHT_CYAN:
|
||||
case LIGHT_WHITE:
|
||||
std::cout << SEQ_BACKGROUND_LIGHT << background << "m";
|
||||
break;
|
||||
case DEFAULT:
|
||||
default:
|
||||
std::cout << SEQ_BACKGROUND << background << "m";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::temp(Chessboard* chessboard) {
|
||||
for (int rank = 8; rank >= 1; rank--) {
|
||||
if (rank == 8) GenerateTopOrBottomBorder(true);
|
||||
|
||||
std::vector<std::string> temp;
|
||||
|
||||
for (int heightOfField = 0; heightOfField < 3; heightOfField++) {
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') {
|
||||
temp.push_back((heightOfField == 1) ? " " + std::to_string(rank) + " " : " ");
|
||||
temp.push_back(ChessboardVisualizerGraphic::VERTICAL_LINE);
|
||||
}
|
||||
|
||||
temp.push_back(GenerateBoardField(chessboard, file, rank, heightOfField));
|
||||
|
||||
if (file == 'H') {
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
temp.push_back(ChessboardVisualizerGraphic::VERTICAL_LINE);
|
||||
}
|
||||
}
|
||||
AddRowToBoard(temp);
|
||||
temp.clear();
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
}
|
||||
if (rank == 1) GenerateTopOrBottomBorder(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::AddMenusToChessboard() {
|
||||
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::GenerateChessboard(Chessboard* chessboard) {
|
||||
ClearTerminal();
|
||||
|
||||
board.clear();
|
||||
|
||||
GeneratePlayers(chessboard);
|
||||
|
||||
temp(chessboard);
|
||||
|
||||
AddMenusToChessboard();
|
||||
|
||||
/*HistorieVisualizer history = HistorieVisualizer(15, 3, "Me", "Me");
|
||||
|
||||
std::vector<std::vector<std::string>> historyDisplayVector = history.GetDisplayVector();
|
||||
std::vector<std::vector<std::string>> currentBoard = board;
|
||||
|
||||
for (size_t i = 0; i < historyDisplayVector.size(); i++) {
|
||||
for (size_t j = 0; j < historyDisplayVector[i].size(); j++) {
|
||||
board[i].push_back(" " + historyDisplayVector[i][j]);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
/*this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
DrawFromVector();
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::Draw(Chessboard* chessboard) {
|
||||
ClearTerminal();
|
||||
|
||||
DrawPlayers(chessboard);
|
||||
|
||||
for (int rank = 8; rank >= 1; rank--) {
|
||||
if (rank == 8) DrawTopOrBottomBorder(true);
|
||||
|
||||
for (int heightOfField = 0; heightOfField < 3; heightOfField++) {
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') {
|
||||
(heightOfField == 1) ? std::cout << " " << rank << " " : std::cout << " ";
|
||||
std::cout << ChessboardVisualizerGraphic::VERTICAL_LINE;
|
||||
}
|
||||
|
||||
DrawBoardField(chessboard, file, rank, heightOfField);
|
||||
|
||||
if (file == 'H') {
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
std::cout << ChessboardVisualizerGraphic::VERTICAL_LINE;
|
||||
}
|
||||
}
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if (rank == 1) DrawTopOrBottomBorder(false);
|
||||
}
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::GenerateTopOrBottomBorder(bool top) {
|
||||
std::vector<std::string> temp;
|
||||
|
||||
temp.push_back(" ");
|
||||
|
||||
std::string left = (top) ? ChessboardVisualizerGraphic::TOP_LEFT_CORNER : ChessboardVisualizerGraphic::BOTTOM_LEFT_CORNER;
|
||||
temp.push_back(left);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
temp.push_back(ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE + ChessboardVisualizerGraphic::HORIZONTAL_LINE);
|
||||
}
|
||||
|
||||
std::string right = (top) ? ChessboardVisualizerGraphic::TOP_RIGHT_CORNER : ChessboardVisualizerGraphic::BOTTOM_RIGHT_CORNER;
|
||||
temp.push_back(right);
|
||||
|
||||
AddRowToBoard(temp);
|
||||
if (!top) GenerateFiles();
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::DrawTopOrBottomBorder(bool top) {
|
||||
std::cout << " ";
|
||||
|
||||
std::string left = (top) ? ChessboardVisualizerGraphic::TOP_LEFT_CORNER : ChessboardVisualizerGraphic::BOTTOM_LEFT_CORNER;
|
||||
std::cout << left;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
std::cout << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE << ChessboardVisualizerGraphic::HORIZONTAL_LINE;
|
||||
}
|
||||
|
||||
std::string right = (top) ? ChessboardVisualizerGraphic::TOP_RIGHT_CORNER : ChessboardVisualizerGraphic::BOTTOM_RIGHT_CORNER;
|
||||
std::cout << right;
|
||||
|
||||
std::cout << std::endl;
|
||||
if (!top) DrawFiles();
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::GenerateFiles() {
|
||||
std::vector<std::string> temp;
|
||||
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') {
|
||||
temp.push_back(" ");
|
||||
}
|
||||
|
||||
temp.push_back(" " + std::string(1, file) + " ");
|
||||
|
||||
if (file == 'H') {
|
||||
temp.push_back(" ");
|
||||
}
|
||||
}
|
||||
AddRowToBoard(temp);
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::DrawFiles() {
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') {
|
||||
std::cout << " ";
|
||||
}
|
||||
|
||||
std::cout << " " << file << " ";
|
||||
|
||||
if (file == 'H') {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
std::string ChessboardVisualizerGraphic::GenerateBoardField(Chessboard* chessboard, char file, int rank, int height) {
|
||||
if (height == 1) {
|
||||
ChessPiecePosition* position = new ChessPiecePosition(file, rank);
|
||||
|
||||
if (chessboard->IsEmptyField(position)) {
|
||||
return " ";
|
||||
} else {
|
||||
ChessPiece* piece = chessboard->GetChessPiece(position);
|
||||
return " " + piece->GetUnicode() + " ";
|
||||
}
|
||||
} else {
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::DrawBoardField(Chessboard* chessboard, char file, int rank, int height) {
|
||||
if (file % 2 == (rank % 2)) {
|
||||
this->SetConsoleColor(BLACK, WHITE);
|
||||
} else {
|
||||
this->SetConsoleColor(WHITE, BLACK);
|
||||
}
|
||||
|
||||
if (height == 1) {
|
||||
ChessPiecePosition* position = new ChessPiecePosition(file, rank);
|
||||
|
||||
if (chessboard->IsEmptyField(position)) {
|
||||
std::cout << " ";
|
||||
} else {
|
||||
ChessPiece* piece = chessboard->GetChessPiece(position);
|
||||
std::cout << " " << piece->GetUnicode() << " ";
|
||||
}
|
||||
} else {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::ClearTerminal() {
|
||||
//std::cout << "\033[2J"; // clear the console
|
||||
system("cls");
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::GeneratePlayers(Chessboard* chessboard) {
|
||||
std::vector<std::string> temp;
|
||||
temp.push_back(" ");
|
||||
temp.push_back(chessboard->GetPlayer(ChessPieceColor::White)->GetName() + " vs. " + chessboard->GetPlayer(ChessPieceColor::Black)->GetName());
|
||||
AddRowToBoard(temp);
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::DrawPlayers(Chessboard* chessboard) {
|
||||
std::cout << " ";
|
||||
std::cout << chessboard->GetPlayer(ChessPieceColor::White)->GetName() + " vs. " + chessboard->GetPlayer(ChessPieceColor::Black)->GetName();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void ChessboardVisualizerGraphic::AddRowToBoard(const std::vector<std::string>& row) {
|
||||
board.push_back(row);
|
||||
}
|
||||
|
||||
// board[2] bis board[25] Feld des Schachbretts
|
||||
// in vectoren von 2 bis 25 index von 2 bis 9
|
||||
void ChessboardVisualizerGraphic::DrawFromVector() {
|
||||
size_t lengthOfBoard = BaseVisualizer::GetSumAllCharsFromVector(board[1]);
|
||||
for (int row = 0; row < board.size(); ++row) {
|
||||
for (int column = 0; column < board[row].size(); ++column) {
|
||||
if (row >= 2 && row <= 25 && column >= 2 && column <= 9) {
|
||||
bool isSecondRowOfField = (row % 3 == 2);
|
||||
bool isBlackWhite = (column % 2 == row % 2);
|
||||
|
||||
if ((row - 1) % 3 == 0) { // Change after 3 rows
|
||||
if (isSecondRowOfField) {
|
||||
this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
|
||||
} else {
|
||||
this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
|
||||
}
|
||||
} else {
|
||||
if (isSecondRowOfField) {
|
||||
this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
|
||||
} else {
|
||||
this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
//std::cout << std::setw(lengthOfBoard) << board[row][column];
|
||||
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
}
|
||||
this->SetConsoleColor(DEFAULT, DEFAULT);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}*/
|
@@ -1,48 +0,0 @@
|
||||
/*#ifndef ChessboardVisualizerGraphic_H
|
||||
#define ChessboardVisualizerGraphic_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../Chessboard/ChessboardVisualizer.hpp"*/
|
||||
|
||||
/*enum Colors {
|
||||
BLACK = 0, RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4, MAGENTA = 5, CYAN = 6, WHITE = 7,
|
||||
LIGHT_BLACK = 10, LIGHT_RED = 11, LIGHT_GREEN = 12, LIGHT_YELLOW = 13, LIGHT_BLUE = 14,
|
||||
LIGHT_MAGENTA = 15, LIGHT_CYAN = 16, LIGHT_WHITE = 17, DEFAULT = 9
|
||||
};*/
|
||||
|
||||
/*class ChessboardVisualizerGraphic : public ChessboardVisualizer {
|
||||
protected:
|
||||
inline static const std::string TOP_LEFT_CORNER = "\u2554";
|
||||
inline static const std::string TOP_RIGHT_CORNER = "\u2557";
|
||||
inline static const std::string HORIZONTAL_LINE = "\u2550";
|
||||
inline static const std::string VERTICAL_LINE = "\u2551";
|
||||
inline static const std::string BOTTOM_LEFT_CORNER = "\u255A";
|
||||
inline static const std::string BOTTOM_RIGHT_CORNER = "\u255D";
|
||||
|
||||
private:
|
||||
std::vector<std::vector<std::string>> board;
|
||||
void ClearTerminal();
|
||||
void DrawTopOrBottomBorder(bool top);
|
||||
void GenerateTopOrBottomBorder(bool top);
|
||||
void DrawPlayers(Chessboard* chessboard);
|
||||
void GeneratePlayers(Chessboard* chessboard);
|
||||
std::string GenerateBoardField(Chessboard* chessboard, char file, int rank, int height);
|
||||
void DrawBoardField(Chessboard* chessboard, char file, int rank, int height);
|
||||
void DrawFiles();
|
||||
void GenerateFiles();
|
||||
//void SetConsoleColor(Colors foreground, Colors background);
|
||||
void SetColorsForField();
|
||||
void temp(Chessboard* chessboard);
|
||||
void AddMenusToChessboard();
|
||||
|
||||
public:
|
||||
ChessboardVisualizerGraphic() = default;
|
||||
void Draw(Chessboard* chessboard);
|
||||
void GenerateChessboard(Chessboard* chessboard);
|
||||
void DrawFromVector();
|
||||
void AddRowToBoard(const std::vector<std::string>& row);
|
||||
};
|
||||
|
||||
#endif
|
||||
*/
|
@@ -1,92 +0,0 @@
|
||||
#include "../Chessboard/ChessboardVisualizerText.hpp"
|
||||
#include "../ChessPieces/ChessPiecePosition.hpp"
|
||||
|
||||
/*void ChessboardVisualizerText::Draw(Chessboard* chessboard) {
|
||||
std::cout << "\033[2J"; // clear the console
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << " " << chessboard->GetPlayer(ChessPieceColor::White)->GetName() << " vs. " << chessboard->GetPlayer(ChessPieceColor::Black)->GetName();
|
||||
std::cout << std::endl;
|
||||
|
||||
for (int rank = 8; rank >= 1; rank--) {
|
||||
if (rank == 8) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i == 0) {
|
||||
std::cout << " " << " " << " ";
|
||||
std::cout << "\u250F";
|
||||
} else {
|
||||
std::cout << "\u2533";
|
||||
}
|
||||
std::cout << "\u2501" << "\u2501" << "\u2501";
|
||||
if (i == 7) {
|
||||
std::cout << "\u2513";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') { // Beginn der Zeile
|
||||
std::cout << " " << rank << " ";
|
||||
std::cout << "\u2503";
|
||||
}
|
||||
|
||||
ChessPiecePosition* position = new ChessPiecePosition(file, rank);
|
||||
|
||||
if (chessboard->IsEmptyField(position)) {
|
||||
std::cout << " " << " " << " ";
|
||||
} else {
|
||||
ChessPiece* piece = chessboard->GetChessPiece(position);
|
||||
std::cout << " " << piece->GetUnicode() << " ";
|
||||
}
|
||||
|
||||
std::cout << "\u2503";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
if (rank != 1) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i == 0) {
|
||||
std::cout << " " << " " << " ";
|
||||
std::cout << "\u2523";
|
||||
} else {
|
||||
std::cout << "\u254B";
|
||||
}
|
||||
std::cout << "\u2501" << "\u2501" << "\u2501";
|
||||
if (i == 7) {
|
||||
std::cout << "\u252B";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i == 0) {
|
||||
std::cout << " " << " " << " ";
|
||||
std::cout << "\u2517";
|
||||
} else {
|
||||
std::cout << "\u253B";
|
||||
}
|
||||
std::cout << "\u2501" << "\u2501" << "\u2501";
|
||||
if (i == 7) {
|
||||
std::cout << "\u251B";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
for (char file = 'A'; file <= 'H'; file++) {
|
||||
if (file == 'A') {
|
||||
std::cout << " " << " " << " ";
|
||||
std::cout << " ";
|
||||
} else {
|
||||
std::cout << " ";
|
||||
}
|
||||
std::cout << " " << file << " ";
|
||||
if (file == 'H') {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
*/
|
@@ -1,16 +0,0 @@
|
||||
/*#ifndef ChessboardVisualizerText_H
|
||||
#define ChessboardVisualizerText_H
|
||||
|
||||
#include "../Chessboard/ChessboardVisualizer.hpp"
|
||||
|
||||
class ChessboardVisualizerText : public ChessboardVisualizer {
|
||||
private:
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
ChessboardVisualizerText() = default;
|
||||
void Draw(Chessboard* chessboard);
|
||||
};
|
||||
|
||||
#endif
|
||||
*/
|
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by hamac on 18.12.2024.
|
||||
//
|
||||
|
||||
#include "Chesspiece.h"
|
||||
|
||||
Chesspiece::Chesspiece(char color, std::pair<int, int> position)
|
||||
: color(color), position(position) {}
|
||||
|
||||
std::pair<int, int> Chesspiece::getPosition() { return this->position; };
|
||||
void Chesspiece::setPosition(std::pair<int, int> position) {
|
||||
this->position = position;
|
||||
//Chesspiece::calcAvaibleMoves(); // Brett -> Auswahl Figuren -> Züge gewählte
|
||||
}
|
||||
|
||||
char Chesspiece::getColor() { return color; }
|
||||
void Chesspiece::setColor(char color) { color = color; }
|
||||
|
||||
std::vector<std::string> Chesspiece::getAvaibleMoves() { return avaibleMoves; }
|
||||
|
||||
bool Chesspiece::checkNotation(std::string notation) {
|
||||
std::regex pattern("R^([KQRNBP]?)([a-h][1-8])[-x]([a-h][1-8])([+#]?)$");
|
||||
std::smatch match;
|
||||
return (std::regex_search(notation, match, pattern) ? true : false);
|
||||
}
|
46
Chesspiece.h
46
Chesspiece.h
@@ -1,46 +0,0 @@
|
||||
//
|
||||
// Created by hamac on 19.12.2024.
|
||||
//
|
||||
|
||||
#ifndef CHESSPIECE_H
|
||||
#define CHESSPIECE_H
|
||||
|
||||
//
|
||||
// Created by hamac on 18.12.2024.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
|
||||
class Chesspiece {
|
||||
private:
|
||||
/* fields */
|
||||
// ToDo: von char auf enum Color {W, B} umstellen
|
||||
char color;
|
||||
char identifier; // P,K,...
|
||||
std::pair<int, int> position;
|
||||
// std::vector<std::pair<int, int>>
|
||||
std::vector<std::string> avaibleMoves;
|
||||
|
||||
/* methods */
|
||||
virtual std::vector<std::string> calcAvaibleMoves() = 0;
|
||||
|
||||
public:
|
||||
Chesspiece(char color, std::pair<int, int> position);
|
||||
|
||||
virtual ~Chesspiece() = default;
|
||||
|
||||
std::pair<int, int> getPosition();
|
||||
void setPosition(std::pair<int, int> position);
|
||||
|
||||
char getColor();
|
||||
void setColor(char color);
|
||||
|
||||
std::vector<std::string> getAvaibleMoves();
|
||||
|
||||
bool checkNotation(std::string notation);
|
||||
};
|
||||
|
||||
|
||||
#endif //CHESSPIECE_H
|
254
MenuController.cpp
Normal file
254
MenuController.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
#include "MenuController.hpp"
|
||||
#include "Player/Player.hpp"
|
||||
#include "Visualizer/BaseVisualizer.hpp"
|
||||
#include "Visualizer/InstructionsVisualizer.hpp"
|
||||
#include "Visualizer/ImportVisualizer.hpp"
|
||||
#include "Visualizer/PlayingViewVisualizer.hpp"
|
||||
#include "Visualizer/PlaySelectVisualizer.hpp"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
MenuController::MenuController() {
|
||||
// Konstruktor, falls nötig
|
||||
}
|
||||
|
||||
MenuController::~MenuController() {
|
||||
// Destruktor, falls nötig
|
||||
}
|
||||
|
||||
void MenuController::HandlePlayingNavigation(std::string choice, Chessboard& chessboard, PlayingViewVisualizer& playView, bool isGameOver) {
|
||||
if (choice.empty() == false) {
|
||||
if (choice.at(0) == '$') {
|
||||
if (choice == "$0") {
|
||||
return;
|
||||
} else if (choice == "$1") {
|
||||
HandleThirdOption();
|
||||
} else if (choice == "$2") {
|
||||
chessboard.ExportFilePGN("chessgames/save_games/");
|
||||
} else if (choice == "$3") {
|
||||
if (isGameOver) {
|
||||
playView.SetMessage("Game is over! No moves allowed.");
|
||||
} else {
|
||||
chessboard.SetWinner(chessboard.GetOpponentPlayer());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isGameOver) {
|
||||
playView.SetMessage("Game is over! No moves allowed.");
|
||||
} else {
|
||||
playView.SetMessage(chessboard.MoveChessPiece(choice));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuController::HandleFirstOption() {
|
||||
PlaySelectVisualizer playerSelect(3);
|
||||
|
||||
std::string choiceA;
|
||||
std::string choiceB;
|
||||
|
||||
do {
|
||||
playerSelect.SetLabelPlayerName("first player");
|
||||
choiceA = playerSelect.ShowMenu();
|
||||
|
||||
if (choiceA.length() > 40) {
|
||||
choiceA.clear();
|
||||
}
|
||||
} while (choiceA.empty());
|
||||
|
||||
do {
|
||||
playerSelect.SetLabelPlayerName("second player");
|
||||
choiceB = playerSelect.ShowMenu();
|
||||
|
||||
if (choiceB.length() > 40) {
|
||||
choiceB.clear();
|
||||
};
|
||||
} while (choiceB.empty());
|
||||
|
||||
// Spieler initialisieren
|
||||
Player* playerA = new Player(choiceA);
|
||||
Player* playerB = new Player(choiceB);
|
||||
|
||||
// Schachbrett initialisieren
|
||||
Chessboard chessboard;
|
||||
chessboard.SetPlayersRdm(playerA, playerB);
|
||||
chessboard.SetStartingPosition();
|
||||
chessboard.UpdateChessPieces();
|
||||
|
||||
SetChessboard(&chessboard);
|
||||
|
||||
PlayingViewVisualizer playView(&chessboard, 4, 12);
|
||||
|
||||
std::string choiceChessboard;
|
||||
|
||||
do {
|
||||
while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
|
||||
choiceChessboard = playView.ShowMenu();
|
||||
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, false);
|
||||
}
|
||||
|
||||
std::string winner = chessboard.GetWinner();
|
||||
choiceChessboard = "$0";
|
||||
|
||||
if (winner.empty()) {
|
||||
playView.SetMessage("Game is over! - Draw");
|
||||
} else {
|
||||
playView.SetMessage("Game is over! - " + winner + " has won the game!");
|
||||
}
|
||||
} while (choiceChessboard != "$0");
|
||||
|
||||
do {
|
||||
choiceChessboard = playView.ShowMenu();
|
||||
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, true);
|
||||
} while (choiceChessboard != "$0");
|
||||
|
||||
|
||||
// while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
|
||||
// playView.DisplayElement();
|
||||
|
||||
// std::string input;
|
||||
// std::cout << "\x1B[u"; // Cursor-Positionierung
|
||||
// std::cin >> input;
|
||||
|
||||
// std::string command = ExtractAfterDollar(input);
|
||||
// if (!command.empty()) {
|
||||
// HandleCommandOptions(command);
|
||||
// if (command == "0") {
|
||||
// return;
|
||||
// }
|
||||
// } else {
|
||||
// std::string status = chessboard.MoveChessPiece(input);
|
||||
// if (status.empty() == false) {
|
||||
// playView.SetMessage(status);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// std::string winner = chessboard.GetWinner();
|
||||
|
||||
// if (winner.empty()) {
|
||||
// playView.SetMessage("Game is over! - Draw");
|
||||
// } else {
|
||||
// playView.SetMessage("Game is over! - " + winner + " has won the game!");
|
||||
// }
|
||||
|
||||
// while (true) {
|
||||
// playView.DisplayElement();
|
||||
// std::string input;
|
||||
// std::cout << "\x1B[u"; // Cursor-Positionierung
|
||||
// std::cin >> input;
|
||||
|
||||
// std::string command = ExtractAfterDollar(input);
|
||||
// if (command == "0") {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void MenuController::HandleSecondOption() {
|
||||
ImportVisualizer importSelect;
|
||||
|
||||
std::string filePath;
|
||||
|
||||
do {
|
||||
filePath = importSelect.ShowMenu();
|
||||
|
||||
if (std::filesystem::exists(filePath) == false) {
|
||||
filePath.clear();
|
||||
}
|
||||
} while (filePath.empty());
|
||||
|
||||
Chessboard chessboard;
|
||||
chessboard.SetStartingPosition();
|
||||
chessboard.UpdateChessPieces();
|
||||
SetChessboard(&chessboard);
|
||||
|
||||
std::string status = chessboard.ImportFilePGN(filePath);
|
||||
|
||||
PlayingViewVisualizer playView(&chessboard, 4, 12);
|
||||
playView.SetMessage(status);
|
||||
std::string choiceChessboard;
|
||||
|
||||
do {
|
||||
while (!chessboard.IsCheckmate() && !chessboard.IsStalemate() && !chessboard.IsDraw() && chessboard.IsFinished() == false) {
|
||||
choiceChessboard = playView.ShowMenu();
|
||||
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, false);
|
||||
}
|
||||
|
||||
std::string winner = chessboard.GetWinner();
|
||||
choiceChessboard = "$0";
|
||||
|
||||
if (winner.empty()) {
|
||||
playView.SetMessage("Game is over! - Draw");
|
||||
} else {
|
||||
playView.SetMessage("Game is over! - " + winner + " has won the game!");
|
||||
}
|
||||
} while (choiceChessboard != "$0");
|
||||
|
||||
do {
|
||||
choiceChessboard = playView.ShowMenu();
|
||||
this->HandlePlayingNavigation(choiceChessboard, chessboard, playView, true);
|
||||
} while (choiceChessboard != "$0");
|
||||
}
|
||||
|
||||
// ToDo:: Hier muss aus irgendeinem Grund immer zweimal die Eingabe abgeschickt werden. Why!?
|
||||
void MenuController::HandleThirdOption() {
|
||||
InstructionsVisualizer instructions;
|
||||
instructions.DrawView();
|
||||
}
|
||||
|
||||
// void MenuController::HandleCommandOptions(const std::string& command) {
|
||||
// if (command == "1") {
|
||||
// HandleThirdOption();
|
||||
// return;
|
||||
// } else if (command == "2") {
|
||||
// CHESSBOARD->ExportFilePGN("chessgames/save_games/");
|
||||
// std::cout << "Save game functionality is not implemented yet.\n";
|
||||
// } else if (command == "3") {
|
||||
// CHESSBOARD->SetWinner(CHESSBOARD->GetOpponentPlayer());
|
||||
// return;
|
||||
// } else if (command == "0") { // exit
|
||||
// return;
|
||||
// } else {
|
||||
// std::cout << "Invalid command. Please try again.\n";
|
||||
// }
|
||||
// }
|
||||
|
||||
// std::string MenuController::ExtractAfterDollar(const std::string& userInput) {
|
||||
// if (!userInput.empty() && userInput[0] == '$') {
|
||||
// return userInput.substr(1); // Rückgabe des Teils nach '$'
|
||||
// }
|
||||
// return ""; // Leerer String, wenn kein '$' am Anfang
|
||||
// }
|
||||
|
||||
// Chessboard* MenuController::GetChessboard() {
|
||||
// return CHESSBOARD;
|
||||
// }
|
||||
|
||||
void MenuController::SetChessboard(Chessboard* chessboard) {
|
||||
CHESSBOARD = chessboard;
|
||||
}
|
||||
|
||||
// std::string MenuController::trim(const std::string& str) {
|
||||
// size_t start = str.find_first_not_of(" \t\n\r\f\v");
|
||||
// if (start == std::string::npos) return ""; // Nur Leerzeichen
|
||||
// size_t end = str.find_last_not_of(" \t\n\r\f\v");
|
||||
// return str.substr(start, end - start + 1);
|
||||
// }
|
||||
|
||||
// std::vector<std::string> MenuController::split(const std::string& str, char delimiter, bool trimWhitespace) {
|
||||
// std::vector<std::string> tokens;
|
||||
// std::istringstream stream(str);
|
||||
// std::string token;
|
||||
|
||||
// while (std::getline(stream, token, delimiter)) {
|
||||
// if (trimWhitespace) {
|
||||
// token = trim(token); // Trimme die Tokens, falls gewünscht
|
||||
// }
|
||||
// tokens.push_back(token);
|
||||
// }
|
||||
|
||||
// return tokens;
|
||||
// }
|
30
MenuController.hpp
Normal file
30
MenuController.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef MENU_CONTROLLER_HPP
|
||||
#define MENU_CONTROLLER_HPP
|
||||
|
||||
#include "Chessboard/Chessboard.hpp"
|
||||
#include "Visualizer/PlayingViewVisualizer.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
class MenuController {
|
||||
private:
|
||||
std::string ExtractAfterDollar(const std::string& userInput);
|
||||
void HandlePlayingNavigation(std::string choice, Chessboard& chessboard, PlayingViewVisualizer& playView, bool isGameOver);
|
||||
|
||||
Chessboard* CHESSBOARD;
|
||||
|
||||
public:
|
||||
MenuController();
|
||||
~MenuController();
|
||||
|
||||
void HandleFirstOption();
|
||||
void HandleSecondOption();
|
||||
void HandleThirdOption();
|
||||
// void HandleCommandOptions(const std::string& command);
|
||||
// Chessboard* GetChessboard();
|
||||
void SetChessboard(Chessboard* chessboard);
|
||||
// std::string trim(const std::string& str);
|
||||
// std::vector<std::string> split(const std::string& str, char delimiter, bool trimWhitespace = false);
|
||||
};
|
||||
|
||||
#endif // MENU_CONTROLLER_HPP
|
60
OldCode.txt
60
OldCode.txt
@@ -1,60 +0,0 @@
|
||||
void firstVersion() {
|
||||
const std::string white = "\u2B1C";
|
||||
const std::string black = "\u2B1B";
|
||||
|
||||
std::string brett[8][8];
|
||||
|
||||
std::string field;
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
if (y % 2 == 0) {
|
||||
field = (x % 2 == 0) ? "\u2B1C" : "\u2B1B";
|
||||
}
|
||||
else {
|
||||
field = (x % 2 == 0) ? "⬛" : "⬜";
|
||||
}
|
||||
std::cout << field;
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void secondVersion() {
|
||||
//wchar_t t = 0x25FF;
|
||||
|
||||
// Horizontale Linie u2500
|
||||
// Vertikale Linie u2502
|
||||
// Top Right Corner u250C
|
||||
// Top Left Corner u2510
|
||||
// Bottom Right Corner u2514
|
||||
// Bottom Left Corner u2518
|
||||
|
||||
std::string topRightCorner = "\u2554";
|
||||
std::string topLeftCorner = "\u2557";
|
||||
std::string bottomLeftCorner = "\u255A";
|
||||
std::string bottomRightCorner = "\u255D";
|
||||
std::string horizontalLine = "\u2550\u2550";
|
||||
std::string verticalLine = "\u2551";
|
||||
std::string crossSuc = "\u256C";
|
||||
std::string leftSide = "\u2560";
|
||||
std::string rightSide = "\u2563";
|
||||
std::string topSide = "\u2566";
|
||||
std::string bottomSide = "\u2569";
|
||||
|
||||
std::string firstLine = "\u2554\u2550\u2566";
|
||||
std::string line;
|
||||
|
||||
for (int row = 0; row < 9; ++row) {
|
||||
for (int col = 0; col < 8; ++col) {
|
||||
if (row == 0 && col > 0) line += topSide + horizontalLine;
|
||||
if (row == 8 && col > 0) line += bottomSide + horizontalLine;
|
||||
if (col == 0 && row < 8 && row > 0) line += leftSide + horizontalLine;
|
||||
if (row > 0 && row < 8 && col > 0) line += crossSuc + horizontalLine;
|
||||
if (col == 7 && row < 8 && row > 0) line += rightSide;
|
||||
if (row == 0 && col == 0) line += topRightCorner + horizontalLine;
|
||||
if (row == 8 && col == 0) line += bottomLeftCorner + horizontalLine;
|
||||
if (row == 0 && col == 7) line += topLeftCorner + "\n" + verticalLine;
|
||||
if (row == 8 && col == 7) line += bottomRightCorner;
|
||||
}
|
||||
line += "\n";
|
||||
}
|
174
README.md
174
README.md
@@ -1,119 +1,69 @@
|
||||
# c/c++ Abschlussprojekt - Schach
|
||||
# TurboSchach
|
||||
|
||||
## Notwendige Umsetzungen
|
||||
## Kompilieren / Ausführen
|
||||
Für die Ausführung von TurboSchach sollte die Konsole / das Terminal im Vollbildmodus geöffnet sein. Durch ein zu kleines Terminal kann es zu Verschiebungen in der Benutzeroberfläche kommen. Um TurboSchach kompilieren zu können wird mindestens C++ 17 benötigt.
|
||||
|
||||
1. Klasse für Spielbrett
|
||||
2. Oberklasse für Spielfiguren
|
||||
1. Bauer
|
||||
2. Dame
|
||||
3. König
|
||||
4. Läufer
|
||||
5. Turm
|
||||
6. Springer
|
||||
3. Fancy User Interface
|
||||
4. Speicherung des Spielbretts
|
||||
5. Unentschieden anbieten
|
||||
6. Aufgegeben
|
||||
### Linux und MacOS
|
||||
|
||||
### Spielbrett
|
||||
|
||||
- 8x8 Matrix
|
||||
- ANSI Linien checken
|
||||
- Unterscheidung von schwarzen und weißen Feldern
|
||||
- UTF-8 Spielfiguren
|
||||
- draw() Funktion
|
||||
- movement
|
||||
- Schachnotation
|
||||
- oder Klickbar?
|
||||
- Beschriftung des Spielbretts
|
||||
|
||||
### Spielfiguren
|
||||
|
||||
- Interface für Implementierung?
|
||||
- Default Felder:
|
||||
- Art der Figure
|
||||
- UTF-8 Code
|
||||
- Schlagen: Ich sehe dich nach movement Regeln -> Du stirbst
|
||||
- Bauer:
|
||||
- Movement: 1 Felder, außer bei Start 1-2 Felder
|
||||
- Schlagen: 1 Feld vor Diagonal
|
||||
- Spezialmove:
|
||||
- Beförderung
|
||||
- En Passent - Wie?
|
||||
- Dame:
|
||||
- Movement: Fuck it, i do what i want
|
||||
- König:
|
||||
- Movement: Körperklaus. Ich kann nur ein Feld nach überall
|
||||
- Spezialmove: Castlen
|
||||
- Läufer:
|
||||
- Movement: Die Diagnal ist mir
|
||||
- Turm:
|
||||
- Movement: Vertikal und Horizontal
|
||||
- Springer:
|
||||
- Movement: L-Bewegung (2 nach vorn + 1 nach links oder rechts); Krake
|
||||
- Spezial Moves:
|
||||
- Rochade -> Kurz/Lang
|
||||
- En Passant
|
||||
- Stalemate
|
||||
- Bauer: 2 Felder
|
||||
- Umwandeln
|
||||
|
||||
## Optional wenn Lust und Zeit?
|
||||
|
||||
1. Bedienung per Maus
|
||||
2. Multiplayer
|
||||
3. Historie der Spielzüge
|
||||
4. Gravejard der geschlagenen Figuren
|
||||
5. König platzieren -> Anzeigen wer gewinnt
|
||||
|
||||
# Gedankensammlung
|
||||
- Initialisierung:
|
||||
- Brett zeichnen
|
||||
- Figuren mit Zugmöglichkeiten ermitteln
|
||||
- Züge kalkulieren
|
||||
- Objekt mit allen Figuren erstellen -> alle Figuren initialisieren
|
||||
- Kalkulation der Züge
|
||||
- Anhand der aktuellen Position
|
||||
- Mit einbeziehen, dass Zug König nicht in Mate versetzt (verboten)
|
||||
- Sonder Züge, wie En passant, Rochade (Lang, Kurz), Bauern zwei Feld, beachten
|
||||
- Prüfen, ob andere Figuren im Weg stehen
|
||||
- Array von Linked Lists
|
||||
- Array Index steht für Richtung von Bewegungen (diagonalen, L, Gerade)
|
||||
- alles droppen, was nach pos mit Figur kommt
|
||||
|
||||
## Figuren
|
||||
|
||||
- Läufer (Bishop)
|
||||
- König (King)
|
||||
- Königin (Queen)
|
||||
- Turm (Rook)
|
||||
- Bauer (Pawn)
|
||||
- Pferd (Knight)
|
||||
|
||||
## ToDo
|
||||
- Speicherfunktion
|
||||
- ToDos abarbeiten
|
||||
- Anleitung schreiben
|
||||
- Befehlen während des Spiel implementieren
|
||||
- Bewegen funktioniert nicht -> Fixen!!!!
|
||||
- Historie -> Spielzüge speichern und anzeigen
|
||||
- Meldung für falschen Zug (Fehlermeldungen beim Spielen)
|
||||
- Nach Beenden nicht Pfad in Anzeige stehen lassen
|
||||
- Dark Mode
|
||||
|
||||
## Erledigt
|
||||
- Schachnotation (Lange)
|
||||
- Menü (ASCII Art of TurboSchach)
|
||||
- Startmenü
|
||||
- Spielmenü mit Historie, Kommand
|
||||
- Plattformunabhängiges CMD clearing vor dem Zeichnen
|
||||
- Spezialbewegung (Rochade, Umwandlung, En passant)
|
||||
|
||||
## Build
|
||||
```
|
||||
g++ -o chess.exe main.cpp ChessPieces/*.cpp Chessboard/*.cpp Player/*.cpp Visualizer/*.cpp
|
||||
# build
|
||||
make
|
||||
|
||||
# run
|
||||
make run
|
||||
```
|
||||
|
||||
## Voraussetzungen
|
||||
### Microsoft Windows
|
||||
|
||||
- C++ 17
|
||||
```
|
||||
# build
|
||||
g++ -std=c++17 -o chess.exe main.cpp MenuController.cpp ChessPieces/*.cpp Chessboard/*.cpp Player/*.cpp Visualizer/*.cpp
|
||||
|
||||
# run
|
||||
./chess.exe
|
||||
|
||||
# build and run (PowerShell)
|
||||
.\run
|
||||
```
|
||||
|
||||
## Algebraische Notation
|
||||
Um die Figuren auf dem Schachbrett zu bewegen, wird die kurze algebraische Notation nach [FIDE](https://handbook.fide.com/chapter/E012023) (siehe Appendix C) unterstützt. Es werden die Schachfiguren sowohl in deutscher als auch in englischer Sprache unterstützt.
|
||||
|
||||
| Schachfigur | Deutsch | Englisch |
|
||||
| ----------- | ------- | -------- |
|
||||
| Bauer (Pawn) | B | P |
|
||||
| Springer (Knight) | S | N |
|
||||
| Läufer (Bishop) | L | B |
|
||||
| Turm (Rook) | T | R |
|
||||
| Dame (Queen) | D | Q |
|
||||
| König (King) | K | K |
|
||||
|
||||
Bei der kurzen Notation wird immer nur das Zielfeld eines Spielzuges genannt. Sollte der Ursprung nicht eindeutig sein kann auch die Spalte oder Zeile der zu bewegenden Figur genannt werden. So gibt der Spielzug `dxe5` an dass der Bauer in der Spalte D auf das Feld E5 zieht. Das `x` gibt an dass dabei eine Spielfigur des Gegeners geschlagen wird. Dies muss aber nicht zwingend angegeben werden.
|
||||
Der Bauer wird in den Spielzügen nicht benannt. Der Spielzug `b4` ist daher der Zug eines Bauern auf das Feld B4. Alle anderen Schachfiguren werden im Zug mit ihrem entsprechenden Buchstaben genannt. So gibt der Spielzug `Bc4` an dass der Läufer auf das Feld C4 gezogen wird.
|
||||
|
||||
### Beispiele
|
||||
|
||||
- `(=)` Draw: Das Draw wird dann aktiv wenn dieses im nächsten Spielzug vom Gegner bestätigt wird.
|
||||
- `b4` Der Bauer zieht auf das Feld B4.
|
||||
- `Bc4` Der Läufer zieht auf das Feld C4.
|
||||
- `0-0` Kleine Rochade (Rochade am Königsflügel)
|
||||
- `0-0-0` Große Rochade (Rochade am Damenflügel)
|
||||
- `d8Q` Umwandlung: Der Bauer zieht auf D8 und wandelt sich zur Dame.
|
||||
|
||||
## PGN (Portable Game Notation)
|
||||
TurboSchach unterstützt das Datenformat [PGN (Portable Game Notation)](https://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm), welches zur Speicherung von Schachpartien verwendet wird. Auf der Website https://www.chessgames.com/ werden beispielsweise viele Schachpartien von offiziellen Turnieren im PGN-Format zur Verfügung gestellt. Diese Dateien können in TurboSchach importiert werden. Über den Menüpunkt 2 direkt nach dem Start der Anwendung ist dieser Import möglich.
|
||||
|
||||
Diese PGN-Dateien wurden auch zum Testen der Anwendung verwendet. Nachfolgend einige Schachspiele mit bestimmten Eigenschaften:
|
||||
|
||||
- [Jack Rudd vs Martin Simons](https://www.chessgames.com/perl/chessgame?gid=1588906) vom 09.08.2000 - Schachmatt
|
||||
- [Tim Jaksland vs Line Jin Jorgensen](https://www.chessgames.com/perl/chessgame?gid=1482551) vom 22.01.2008 - Schachmatt
|
||||
- [Gabriel Sargissian vs Nigel Short](https://www.chessgames.com/perl/chessgame?gid=1775611) vom 04.10.2014 - En Passant (`axb6`)
|
||||
- [Ulf Andersson vs Daniel Stellwagen](https://www.chessgames.com/perl/chessgame?gid=1427255) vom 27.08.2006 - En Passant (`bxc6+` und `dxe6`)
|
||||
- [Garry Kasparov vs Kiril Georgiev](https://www.chessgames.com/perl/chessgame?gid=1258478) vom 20.02.1988 - Stalemate
|
||||
- [Magnus Carlsen vs Hans Niemann](https://www.chessgames.com/perl/chessgame?gid=2821644) vom 31.12.2024
|
||||
|
||||
## Ausblick
|
||||
|
||||
- Multiplayer-Modus
|
||||
- Abspielen der Schachpartien (Schritt für Schritt) aus einer PGN-Datei
|
||||
- Anzeige der nächstmöglichen Züge bei Auswahl einer Figur
|
@@ -1,8 +1,15 @@
|
||||
#include "BaseVisualizer.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
void BaseVisualizer::ClearTerminal() {
|
||||
//std::cout << "\033[2J";
|
||||
#ifdef __linux__
|
||||
system("clear");
|
||||
#elif _WIN32
|
||||
system("cls");
|
||||
#else
|
||||
system("clear");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string>>* BaseVisualizer::GetDisplayVector() {
|
||||
@@ -88,16 +95,12 @@ void BaseVisualizer::GenerateCenteredString(const size_t widthOfMenu, const std:
|
||||
}
|
||||
|
||||
void BaseVisualizer::DisplayElement() {
|
||||
int temp;
|
||||
for (const auto& row : display_vector) {
|
||||
for (const auto& cell : row) {
|
||||
std::cout << cell;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << "\x1B[u";
|
||||
//std::cout << "Select option" << std::endl;
|
||||
std::cin >> temp;
|
||||
}
|
||||
|
||||
size_t BaseVisualizer::CalculateMaxMenuWidth(const size_t longestStringLength, const size_t padding) {
|
||||
@@ -136,6 +139,7 @@ void BaseVisualizer::GenerateTableTopBottom(const size_t totalLength, const bool
|
||||
display_vector.push_back({result + ((top) ? ((single) ? BaseVisualizer::TOP_RIGHT_CORNER_SINGLE : BaseVisualizer::TOP_RIGHT_CORNER) : ((single) ? BaseVisualizer::BOTTOM_RIGHT_CORNER_SINGLE : BaseVisualizer::BOTTOM_RIGHT_CORNER))});
|
||||
}
|
||||
|
||||
// Todo: pair anstatt vector
|
||||
void BaseVisualizer::GenerateTableLine(const float length, const std::vector<std::string>& str, const bool single) {
|
||||
int firstHalfLength = std::floor(length / 2);
|
||||
std::string result = ((single) ? BaseVisualizer::VERTICAL_LINE_SINGLE : BaseVisualizer::VERTICAL_LINE);
|
||||
@@ -257,3 +261,21 @@ size_t BaseVisualizer::FindMaxLength(const std::vector<std::string> vec) {
|
||||
return max;
|
||||
}
|
||||
|
||||
std::pair<int, int> BaseVisualizer::GetCursorPosition() {
|
||||
std::cout << "\033[6n"; // ANSI-Escape-Sequenz, um die Cursorposition abzufragen
|
||||
std::fflush(stdout); // Ausgabe sofort erzwingen
|
||||
|
||||
int row, col;
|
||||
|
||||
// Eingabe im Format "\033[row;colR" lesen
|
||||
char buf[32];
|
||||
if (std::fgets(buf, sizeof(buf), stdin)) {
|
||||
if (std::sscanf(buf, "\033[%d;%dR", &row, &col) != 2) {
|
||||
row = col = -1; // Fehlerbehandlung
|
||||
}
|
||||
} else {
|
||||
row = col = -1; // Fehlerbehandlung
|
||||
}
|
||||
|
||||
return std::pair<int, int>(row, col); // Rückgabe als Tupel
|
||||
};
|
@@ -55,6 +55,7 @@ class BaseVisualizer {
|
||||
void GenerateTableSeperator(const float length, const bool single);
|
||||
void GenerateBoxSeperator(const float length, const bool single);
|
||||
void SetConsoleColor(Colors foreground, Colors background);
|
||||
std::pair<int, int> GetCursorPosition();
|
||||
|
||||
static size_t GetSumAllCharsFromVector(const std::vector<std::string>& vec);
|
||||
static size_t CountVisibleCharacters(const std::string& str);
|
||||
|
@@ -1,13 +1,20 @@
|
||||
#include "CommandMenuVisualizer.hpp"
|
||||
|
||||
// ToDo: Cursor wird nicht an die richtige Stelle gesetzt
|
||||
void CommandMenuVisualizer::GenerateElement() {
|
||||
BaseVisualizer::display_vector.push_back({"Commands"});
|
||||
BaseVisualizer::display_vector.push_back({" Commands"});
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, true);
|
||||
for (const auto& content : menuContent) {
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, true, PADDING);
|
||||
}
|
||||
BaseVisualizer::GenerateBoxSeperator(MAX_MENU_WIDTH, true);
|
||||
std::string str_temp = ((CHESSBOARD->GetCurrentPlayer()->GetColor() == ChessPieceColor::White) ? "White" : "Black");
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Move [" + str_temp + "] : " + "\x1B[s", true, true);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Move [" + str_temp + "] : \x1B[s", true, PADDING);
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, true);
|
||||
display_vector.push_back({" "});
|
||||
BaseVisualizer::display_vector.push_back({std::string(" ").append(GetMessage())});
|
||||
}
|
||||
|
||||
std::string CommandMenuVisualizer::GetMessage() {
|
||||
return this->message;
|
||||
}
|
@@ -11,20 +11,22 @@ class CommandMenuVisualizer : public BaseVisualizer {
|
||||
"",
|
||||
"1 - Instructions",
|
||||
"2 - Save",
|
||||
"3 - Exit",
|
||||
"3 - Resign",
|
||||
"",
|
||||
"8 - Resign",
|
||||
"9 - Draw"
|
||||
"0 - Exit",
|
||||
};
|
||||
|
||||
Chessboard* CHESSBOARD;
|
||||
|
||||
std::string message;
|
||||
|
||||
void GenerateElement() override;
|
||||
|
||||
public:
|
||||
CommandMenuVisualizer(Chessboard* chessboard, size_t padding) : BaseVisualizer(CommandMenuVisualizer::FindMaxLength(menuContent), padding), CHESSBOARD(chessboard) {
|
||||
CommandMenuVisualizer(Chessboard* chessboard, size_t padding, std::string msg) : BaseVisualizer(CommandMenuVisualizer::FindMaxLength(menuContent), padding), CHESSBOARD(chessboard), message(msg) {
|
||||
CommandMenuVisualizer::GenerateElement();
|
||||
}
|
||||
std::string GetMessage();
|
||||
};
|
||||
|
||||
#endif //COMMANDMENUVISUALIZER_HPP
|
||||
|
@@ -1,14 +1,50 @@
|
||||
#include "HistorieVisualizer.hpp"
|
||||
#include <algorithm>
|
||||
#include "../ChessPieces/ChessPieceMove.hpp"
|
||||
|
||||
void HistorieVisualizer::GenerateElement() {
|
||||
BaseVisualizer::display_vector.push_back({"Historie"});
|
||||
BaseVisualizer::GenerateTableTopBottom(MAX_MENU_WIDTH, true, true);
|
||||
|
||||
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {HistorieVisualizer::PLAYER1, HistorieVisualizer::PLAYER2}, true);
|
||||
BaseVisualizer::BaseVisualizer::GenerateTableSeperator(MAX_MENU_WIDTH, true);
|
||||
std::string playerName1 = HistorieVisualizer::PLAYER1;
|
||||
std::string playerName2 = HistorieVisualizer::PLAYER2;
|
||||
|
||||
// ToDo: History einlesen und anzeigen lassenF
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
if (playerName1.length() > 14) {
|
||||
playerName1 = playerName1.substr(0, 11) + "...";
|
||||
}
|
||||
if(playerName2.length() > 14) {
|
||||
playerName2 = playerName2.substr(0, 11) + "...";
|
||||
}
|
||||
|
||||
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {playerName1, playerName2}, true);
|
||||
BaseVisualizer::GenerateTableSeperator(MAX_MENU_WIDTH, true);
|
||||
|
||||
std::vector<ChessPieceMove> moves = this->CHESSBOARD->GetHistoryMoves();
|
||||
|
||||
if (moves.size() % 2 == 0) {
|
||||
moves = std::vector<ChessPieceMove>(moves.end() - std::min<int>(moves.size(), 10), moves.end());
|
||||
} else {
|
||||
moves = std::vector<ChessPieceMove>(moves.end() - std::min<int>(moves.size(), 9), moves.end());
|
||||
}
|
||||
|
||||
std::vector<std::string> rowMoves;
|
||||
int rows = 0;
|
||||
|
||||
for (int moveIndex = 0; moveIndex < moves.size(); moveIndex++) {
|
||||
if (moveIndex % 2 == 0) rowMoves.clear();
|
||||
rowMoves.push_back(moves[moveIndex].ToString());
|
||||
|
||||
if (moveIndex % 2 == 1) {
|
||||
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, rowMoves, true);
|
||||
rows++;
|
||||
} else if (moveIndex == moves.size() - 1) {
|
||||
rowMoves.push_back("");
|
||||
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, rowMoves, true);
|
||||
rows++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int rowIndex = rows; rowIndex < 5; rowIndex++) {
|
||||
BaseVisualizer::GenerateTableLine(MAX_MENU_WIDTH, {"", ""}, true);
|
||||
}
|
||||
|
||||
|
@@ -9,14 +9,13 @@ class HistorieVisualizer : public BaseVisualizer {
|
||||
const std::string PLAYER1;
|
||||
const std::string PLAYER2;
|
||||
|
||||
std::vector<std::vector<std::string>> histories;
|
||||
Chessboard* CHESSBOARD;
|
||||
|
||||
void GenerateElement() override;
|
||||
|
||||
public:
|
||||
HistorieVisualizer(Chessboard* chessbord,const size_t menuWidth, const size_t padding) :
|
||||
BaseVisualizer(menuWidth, padding), histories(5, std::vector<std::string>(2, "")),
|
||||
BaseVisualizer(menuWidth, padding),
|
||||
CHESSBOARD(chessbord),
|
||||
PLAYER1(chessbord->GetPlayer(ChessPieceColor::White)->GetName()),
|
||||
PLAYER2(chessbord->GetPlayer(ChessPieceColor::Black)->GetName())
|
||||
|
36
Visualizer/ImportVisualizer.cpp
Normal file
36
Visualizer/ImportVisualizer.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "ImportVisualizer.hpp"
|
||||
|
||||
void ImportVisualizer::GenerateElement() {
|
||||
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
|
||||
// BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
|
||||
// for (const auto& content : menuContent) {
|
||||
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
|
||||
// }
|
||||
// BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
|
||||
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "You can get a lot of PGN files from chessgames.com.", false, PADDING);
|
||||
// BaseVisualizer::AddEmptyLines(5, MAX_MENU_WIDTH, false);
|
||||
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
|
||||
}
|
||||
void ImportVisualizer::DrawView() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
this->display_vector.clear();
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Please enter a path to a PGN (Portable Game Notation) file:", false, PADDING);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "\x1B[s", false, PADDING);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "On https://chessgames.com/ you will find many more chess", false, PADDING);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "games in PGN format, to import into TurboSchach.", false, PADDING);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
|
||||
BaseVisualizer::DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
}
|
||||
|
||||
std::string ImportVisualizer::ShowMenu() {
|
||||
this->DrawView();
|
||||
std::string choice;
|
||||
std::getline(std::cin, choice);
|
||||
return choice;
|
||||
}
|
22
Visualizer/ImportVisualizer.hpp
Normal file
22
Visualizer/ImportVisualizer.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef ImportVisualizer_HPP
|
||||
#define ImportVisualizer_HPP
|
||||
|
||||
#include "BaseVisualizer.hpp"
|
||||
|
||||
class ImportVisualizer : public BaseVisualizer {
|
||||
private:
|
||||
inline static const std::vector<std::string> menuContent = {
|
||||
"Please enter the path to the PGN file:",
|
||||
"\x1B[s"
|
||||
};
|
||||
void GenerateElement() override;
|
||||
|
||||
public:
|
||||
ImportVisualizer() : BaseVisualizer(60, 4) {
|
||||
ImportVisualizer::GenerateElement();
|
||||
};
|
||||
std::string ShowMenu();
|
||||
void DrawView();
|
||||
};
|
||||
|
||||
#endif //INSTRUCTIONSVISUALIZER_HPP
|
@@ -2,12 +2,19 @@
|
||||
|
||||
void InstructionsVisualizer::GenerateElement() {
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
|
||||
BaseVisualizer::AddEmptyLines(5, MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
|
||||
for (const auto& content : menuContent) {
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
|
||||
}
|
||||
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Enter any key to return to menu: \x1B[s", false, PADDING);
|
||||
BaseVisualizer::AddEmptyLines(5, MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Press enter to continue: \x1B[s", false, PADDING);
|
||||
BaseVisualizer::AddEmptyLines(2, MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
|
||||
}
|
||||
void InstructionsVisualizer::DrawView() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
BaseVisualizer::DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
std::string choice;
|
||||
std::getline(std::cin, choice);
|
||||
}
|
||||
|
@@ -6,14 +6,55 @@
|
||||
class InstructionsVisualizer : public BaseVisualizer {
|
||||
private:
|
||||
inline static const std::vector<std::string> menuContent = {
|
||||
"Hier kommt noch eine Anleitung"
|
||||
"1. Algebraische Notation",
|
||||
"",
|
||||
"Um die Figuren auf dem Schachbrett zu bewegen, wird die kurze algebraische Notation",
|
||||
"FIDE-Handbuch (siehe Appendix C) unterstützt. Es werden die Schachfiguren sowohl in",
|
||||
"deutscher als auch in englischer Sprache unterstützt.",
|
||||
"",
|
||||
"┌───────────────────┬─────────┬──────────┐",
|
||||
"│ Schachfigur │ Deutsch │ Englisch │",
|
||||
"├───────────────────┼─────────┼──────────┤",
|
||||
"│ Bauer (Pawn) │ B │ P │",
|
||||
"│ Springer (Knight) │ S │ N │",
|
||||
"│ Läufer (Bishop) │ L │ B │",
|
||||
"│ Turm (Rook) │ T │ R │",
|
||||
"│ Dame (Queen) │ D │ Q │",
|
||||
"│ König (King) │ K │ K │",
|
||||
"└───────────────────┴─────────┴──────────┘",
|
||||
"",
|
||||
"Bei der kurzen Notation wird immer nur das Zielfeld eines Spielzuges genannt. Sollte",
|
||||
"der Ursprung nicht eindeutig sein kann auch die Spalte oder Zeile der zu bewegenden Figur",
|
||||
"genannt werden. So gibt der Spielzug 'dxe5' an dass der Bauer in der Spalte D auf das Feld",
|
||||
"E5 zieht. Das 'x' gibt an dass dabei eine Spielfigur des Gegeners geschlagen wird. Dies muss",
|
||||
"aber nicht zwingend angegeben werden. Der Bauer wird in den Spielzügen nicht benannt. Der",
|
||||
"Spielzug 'b4' ist daher der Zug eines Bauern auf das Feld B4. Alle anderen Schachfiguren werden",
|
||||
"im Zug mit ihrem entsprechenden Buchstaben genannt. So gibt der Spielzug 'Bc4' an dass der Läufer",
|
||||
"auf das Feld C4 gezogen wird.",
|
||||
"",
|
||||
"Beispiele:",
|
||||
"",
|
||||
" - (=) Angebot für ein Draw. Um das Spiel mit einem Draw zu beenden muss das Angebot direkt im",
|
||||
" nächsten Zug bestätigt werden.",
|
||||
" - b4 Der Bauer zieht auf das Feld B4.",
|
||||
" - Bc4 Der Läufer zieht auf das Feld C4.",
|
||||
" - 0-0 Kleine Rochade (Rochade am Königsflügel)",
|
||||
" - 0-0-0 Große Rochade (Rochade am Damenflügel)",
|
||||
" - d8Q Umwandlung: Der Bauer zieht auf D8 und wandelt sich zur Dame.",
|
||||
"",
|
||||
"2. PGN (Portable Game Notation)",
|
||||
"",
|
||||
"TurboSchach unterstützt das Datenformat PGN, welches zur Speicherung von Schachpartien verwendet",
|
||||
"wird. Auf der Website https://www.chessgames.com/ werden viele Schachpartien von offiziellen Turnieren",
|
||||
"im PGN-Format zur Verfügung gestellt. Diese Dateien können in TurboSchach importiert werden."
|
||||
};
|
||||
void GenerateElement() override;
|
||||
|
||||
public:
|
||||
InstructionsVisualizer() : BaseVisualizer(60, 4) {
|
||||
InstructionsVisualizer() : BaseVisualizer(BaseVisualizer::FindMaxLength(menuContent), 4) {
|
||||
InstructionsVisualizer::GenerateElement();
|
||||
};
|
||||
void DrawView();
|
||||
};
|
||||
|
||||
#endif //INSTRUCTIONSVISUALIZER_HPP
|
||||
|
43
Visualizer/PlaySelectVisualizer.cpp
Normal file
43
Visualizer/PlaySelectVisualizer.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "PlaySelectVisualizer.hpp"
|
||||
|
||||
void PlaySelectVisualizer::GenerateElement() {
|
||||
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
|
||||
// BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
// for (const auto& content : menuContent) {
|
||||
// BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, content, false, PADDING);
|
||||
// }
|
||||
// BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
// BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, int>> PlaySelectVisualizer::GetCursorPositions() {
|
||||
return this->cursorPositions;
|
||||
}
|
||||
|
||||
void PlaySelectVisualizer::AddToCursorPositions(const std::pair<int, int>& position) {
|
||||
this->cursorPositions.push_back(position);
|
||||
}
|
||||
void PlaySelectVisualizer::DrawView() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
this->display_vector.clear();
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, true, false);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
if (this->labelPlayerName.empty()) {
|
||||
this->labelPlayerName = "player";
|
||||
}
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "Please enter a name for the " + this->labelPlayerName + ":", false, PADDING);
|
||||
BaseVisualizer::GenerateBoxMenuLine(MAX_MENU_WIDTH, "\x1B[s", false, PADDING);
|
||||
BaseVisualizer::GenerateEmptyLine(MAX_MENU_WIDTH, false);
|
||||
BaseVisualizer::GenerateTopBottomBorder(MAX_MENU_WIDTH, false, false);
|
||||
BaseVisualizer::DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
}
|
||||
std::string PlaySelectVisualizer::ShowMenu() {
|
||||
this->DrawView();
|
||||
std::string choice;
|
||||
std::getline(std::cin, choice);
|
||||
return choice;
|
||||
}
|
||||
void PlaySelectVisualizer::SetLabelPlayerName(std::string label) {
|
||||
this->labelPlayerName = label;
|
||||
}
|
30
Visualizer/PlaySelectVisualizer.hpp
Normal file
30
Visualizer/PlaySelectVisualizer.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef PLAYSELECTVISUALIZER_HPP
|
||||
#define PLAYSELECTVISUALIZER_HPP
|
||||
|
||||
#include "BaseVisualizer.hpp"
|
||||
|
||||
class PlaySelectVisualizer : public BaseVisualizer {
|
||||
private:
|
||||
std::string labelPlayerName;
|
||||
// ToDo: Exit
|
||||
inline static const std::vector<std::string> menuContent = {
|
||||
"Please enter your names! Enter your names with '&' seperated.",
|
||||
"",
|
||||
"Playernames: \x1B[s"
|
||||
};
|
||||
std::vector<std::pair<int, int>> cursorPositions;
|
||||
|
||||
|
||||
public:
|
||||
PlaySelectVisualizer(size_t padding) : BaseVisualizer(PlaySelectVisualizer::FindMaxLength(menuContent), padding) {
|
||||
PlaySelectVisualizer::GenerateElement();
|
||||
}
|
||||
void GenerateElement();
|
||||
void AddToCursorPositions(const std::pair<int, int>& position);
|
||||
std::vector<std::pair<int, int>> GetCursorPositions();
|
||||
void DrawView();
|
||||
std::string ShowMenu();
|
||||
void SetLabelPlayerName(std::string label);
|
||||
};
|
||||
|
||||
#endif //PLAYSELECTVISUALIZER_HPP
|
@@ -3,12 +3,14 @@
|
||||
#include "HistorieVisualizer.hpp"
|
||||
#include "CommandMenuVisualizer.hpp"
|
||||
|
||||
|
||||
// ToDo: Beim Fenster größer ziehen verschiebt sich die Ansicht
|
||||
void PlayingViewVisualizer::GenerateElement() {
|
||||
position_vector.clear();
|
||||
display_vector.clear();
|
||||
ChessboardVisualizer chessboardVisualizer = ChessboardVisualizer(CHESSBOARD, 2);
|
||||
HistorieVisualizer historieVisualizer = HistorieVisualizer(CHESSBOARD, 32, 2);
|
||||
CommandMenuVisualizer cmdMenuVisualizer = CommandMenuVisualizer(CHESSBOARD, 2);
|
||||
ChessboardVisualizer chessboardVisualizer = ChessboardVisualizer(this->CHESSBOARD, 2);
|
||||
HistorieVisualizer historieVisualizer = HistorieVisualizer(this->CHESSBOARD, 32, 2);
|
||||
CommandMenuVisualizer cmdMenuVisualizer = CommandMenuVisualizer(this->CHESSBOARD, 2, this->GetMessage());
|
||||
|
||||
GeneratePositionVector(chessboardVisualizer.GetDisplayVector(), historieVisualizer.GetDisplayVector(), cmdMenuVisualizer.GetDisplayVector());
|
||||
|
||||
@@ -48,13 +50,15 @@ void PlayingViewVisualizer::GeneratePositionVector(
|
||||
temp.push_back(chessboard_display_vector->at(i).at(0));
|
||||
}
|
||||
|
||||
if (i < historie_display_vector->size()) {
|
||||
temp.push_back(std::string(DISTANCE_BETWEEN_ELEMENTS, ' '));
|
||||
|
||||
if (i < historie_display_vector->size()) {
|
||||
temp.push_back(historie_display_vector->at(i)[0]);
|
||||
} else if (i-3-historie_display_vector->size() < command_menu_display_vector->size()) {
|
||||
temp.push_back(std::string(DISTANCE_BETWEEN_ELEMENTS, ' '));
|
||||
temp.push_back(command_menu_display_vector->at(i-3-historie_display_vector->size())[0]);
|
||||
} else{
|
||||
//} else if (i-3-historie_display_vector->size()-command_menu_display_vector->size()-1 == 0 && !this->GetMessage().empty()) {
|
||||
//temp.push_back(this->GetMessage());
|
||||
} else {
|
||||
temp.push_back({"", ""});
|
||||
}
|
||||
|
||||
@@ -101,3 +105,25 @@ void PlayingViewVisualizer::DisplayElement() {
|
||||
std::string PlayingViewVisualizer::GetMove() {
|
||||
return move;
|
||||
}
|
||||
|
||||
std::string PlayingViewVisualizer::GetMessage() {
|
||||
return this->message;
|
||||
}
|
||||
|
||||
void PlayingViewVisualizer::SetMessage(std::string message) {
|
||||
this->message = message;
|
||||
}
|
||||
|
||||
void PlayingViewVisualizer::DrawView() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
this->DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
}
|
||||
|
||||
std::string PlayingViewVisualizer::ShowMenu() {
|
||||
this->DrawView();
|
||||
this->SetMessage("");
|
||||
std::string choice;
|
||||
std::getline(std::cin, choice);
|
||||
return choice;
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ class PlayingViewVisualizer : public BaseVisualizer {
|
||||
|
||||
Chessboard* CHESSBOARD;
|
||||
std::string move;
|
||||
std::string message = "";
|
||||
|
||||
std::vector<std::vector<std::string>> position_vector;
|
||||
|
||||
@@ -24,6 +25,10 @@ class PlayingViewVisualizer : public BaseVisualizer {
|
||||
BaseVisualizer(110, padding), CHESSBOARD(chessboard), DISTANCE_BETWEEN_ELEMENTS(distance) {}
|
||||
void DisplayElement();
|
||||
std::string GetMove();
|
||||
std::string GetMessage();
|
||||
void SetMessage(std::string message);
|
||||
void DrawView();
|
||||
std::string ShowMenu();
|
||||
};
|
||||
|
||||
#endif //PLAYINGVIEWVISUALIZER_HPP
|
||||
|
@@ -52,15 +52,20 @@ void StartMenuVisualizer::SetSelectedOption(int optionSelect) {
|
||||
selectedOption = selectedOption;
|
||||
};
|
||||
|
||||
void StartMenuVisualizer::DisplayElement1() {
|
||||
void StartMenuVisualizer::DrawView() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
int temp;
|
||||
for (const auto& row : display_vector) {
|
||||
for (const auto& cell : row) {
|
||||
std::cout << cell;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
BaseVisualizer::DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
std::cin >> selectedOption;
|
||||
}
|
||||
|
||||
StartMenuVisualizer::StartMenuOption StartMenuVisualizer::ShowMenu() {
|
||||
this->DrawView();
|
||||
std::string choice;
|
||||
std::getline(std::cin, choice);
|
||||
|
||||
if (choice == "1") return StartMenuOption::NewGame;
|
||||
if (choice == "2") return StartMenuOption::LoadGame;
|
||||
if (choice == "3") return StartMenuOption::Instructions;
|
||||
if (choice == "0") return StartMenuOption::Exit;
|
||||
return StartMenuOption::None;
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ class StartMenuVisualizer : public BaseVisualizer {
|
||||
|
||||
inline static const std::vector<std::string> MENU_OPTIONS = {
|
||||
"1 - New Game",
|
||||
"2 - Load Save",
|
||||
"2 - Load Game",
|
||||
"3 - Instructions",
|
||||
"",
|
||||
"0 - Exit"
|
||||
@@ -30,10 +30,17 @@ class StartMenuVisualizer : public BaseVisualizer {
|
||||
StartMenuVisualizer(size_t padding) : BaseVisualizer(BaseVisualizer::CountVisibleCharacters(StartMenuVisualizer::ACSII_ART_TURBO_SCHACH[0]), padding) {
|
||||
StartMenuVisualizer::GenerateElement();
|
||||
}
|
||||
enum StartMenuOption {
|
||||
NewGame,
|
||||
LoadGame,
|
||||
Instructions,
|
||||
Exit,
|
||||
None
|
||||
};
|
||||
int GetSelectedOption();
|
||||
void SetSelectedOption(int selectedOption);
|
||||
void DisplayElement1();
|
||||
|
||||
void DrawView();
|
||||
StartMenuOption ShowMenu();
|
||||
};
|
||||
|
||||
#endif //STARTMENUVISUALIZER_H
|
||||
|
27
chessgames/Tests/1229276.pgn
Normal file
27
chessgames/Tests/1229276.pgn
Normal file
@@ -0,0 +1,27 @@
|
||||
[Event "Bosna 21st"]
|
||||
[Site "Sarajevo YUG"]
|
||||
[Date "1982.??.??"]
|
||||
[EventDate "1983.03.00"]
|
||||
[Round "?"]
|
||||
[Result "0-1"]
|
||||
[White "Vitomir Arapovic"]
|
||||
[Black "Alexander Beliavsky"]
|
||||
[ECO "C26"]
|
||||
[WhiteElo "?"]
|
||||
[BlackElo "?"]
|
||||
[PlyCount "150"]
|
||||
|
||||
1.e4 e5 2.Nc3 Nf6 3.Bc4 Bc5 4.d3 O-O 5.Nf3 Re8 6.Ng5 Re7 7.O-O
|
||||
h6 8.Nf3 c6 9.d4 exd4 10.e5 Ne8 11.Nxd4 d5 12.exd6 Nxd6 13.Bb3
|
||||
Na6 14.Be3 Qe8 15.Qf3 Bxd4 16.Bxd4 Nf5 17.Rad1 Bd7 18.Qh5 b6
|
||||
19.Qg6 Nxd4 20.Rxd4 Nc5 21.Bc4 Be6 22.Qg3 Bxc4 23.Rxc4 Rd8
|
||||
24.Rg4 f5 25.Rg6 Rd4 26.Rd6 f4 27.Qg6 Qxg6 28.Rxg6 Ne6 29.h4
|
||||
h5 30.g4 fxg3 31.Rxg3 Rf7 32.Re1 Nc5 33.Re8+ Kh7 34.Rg5 Rxh4
|
||||
35.b4 Nd7 36.Ne4 Nf6 37.Nxf6+ Rxf6 38.Re7 Rg6 39.Rxg6 Kxg6
|
||||
40.Re6+ Kh7 41.a3 Rc4 42.Re7 Rxc2 43.Rxa7 Rc4 44.Kg2 b5 45.Ra6
|
||||
g6 46.Ra8 Kh6 47.Rh8+ Kg5 48.Rg8 Kf5 49.Rf8+ Kg4 50.Rf6 g5
|
||||
51.Rf8 Rc3 52.Ra8 h4 53.a4 h3+ 54.Kh2 Rc2 55.Kg1 Rb2 56.axb5
|
||||
cxb5 57.Ra3 Kh4 58.Rd3 Rxb4 59.Kh2 g4 60.Rd5 Rb2 61.Kg1 Rb1+
|
||||
62.Kh2 Rf1 63.Rxb5 Rxf2+ 64.Kg1 Rc2 65.Rb4 Re2 66.Ra4 Kg3
|
||||
67.Ra1 Re3 68.Kh1 Kf3 69.Rf1+ Ke2 70.Rf8 g3 71.Kg1 Re4 72.Rh8
|
||||
Kf3 73.Rf8+ Rf4 74.Rg8 Rf7 75.Rh8 h2+ 0-1
|
29
chessgames/Tests/1258478.pgn
Normal file
29
chessgames/Tests/1258478.pgn
Normal file
@@ -0,0 +1,29 @@
|
||||
[Event "Wch-blitz"]
|
||||
[Site "Saint John CAN"]
|
||||
[Date "1988.02.20"]
|
||||
[EventDate "1988.02.19"]
|
||||
[Round "3"]
|
||||
[Result "1/2-1/2"]
|
||||
[White "Garry Kasparov"]
|
||||
[Black "Kiril Dimitrov Georgiev"]
|
||||
[ECO "A29"]
|
||||
[WhiteElo "2750"]
|
||||
[BlackElo "2595"]
|
||||
[PlyCount "155"]
|
||||
|
||||
1. c4 e5 2. Nc3 Nf6 3. Nf3 Nc6 4. g3 d5 5. cxd5 Nxd5 6. Bg2
|
||||
Nb6 7. O-O Be7 8. a3 a5 9. d3 O-O 10. Be3 Be6 11. Na4 Nd5
|
||||
12. Bc5 Bd6 13. Rc1 h6 14. Nd2 Rc8 15. Ne4 b6 16. Nxd6 cxd6
|
||||
17. Bxb6 Nxb6 18. Rxc6 Rb8 19. Nxb6 Rxb6 20. Qc2 Qb8 21. Rxb6
|
||||
Qxb6 22. Rb1 Bb3 23. Qd2 Rb8 24. Rc1 Be6 25. Rc2 d5 26. h4 a4
|
||||
27. Bf3 Qd4 28. e3 Qb6 29. d4 e4 30. Be2 Qb3 31. Kg2 g6
|
||||
32. Bd1 Kg7 33. Qc1 Qb6 34. Rd2 Bd7 35. Qc5 Qxc5 36. dxc5 Bc6
|
||||
37. Kf1 Kf6 38. Ke1 Ke5 39. Rc2 Rb5 40. Kd2 d4 41. exd4+ Kxd4
|
||||
42. Be2 Rxc5 43. Rxc5 Kxc5 44. Ke3 f5 45. g4 Kd5 46. gxf5 gxf5
|
||||
47.Kf4 Ke6 48. Bc4+ Kf6 49. b4 axb3 50. Bxb3 Bb5 51.a4 Ba6
|
||||
52.Bd5 Bc8 53.Bc6 Ke6 54.Bb5 Kd6 55. Bf1 Kc5 56.Bh3 Kb4
|
||||
57.Bxf5 Ba6 58.Bxe4 Kxa4 59.Ke5 Kb4 60. f4 Kc5 61.f5 Bc4 62.f6
|
||||
Bf7 63.Bf5 Kc6 64.Be6 Bg6 65.f7 Bxf7 66. Bxf7 Kd7 67.Kf6 Kd6
|
||||
68.h5 Kd7 69.Kg6 Ke7 70.Ba2 Ke8 71. Kxh6 Kf8 72.Kg6 Ke7 73.h6
|
||||
Kd6 74.h7 Kc5 75.h8=Q Kb4 76. Qd4+ Kb5 77.Bd5 Ka6 78.Qc5
|
||||
1/2-1/2
|
22
chessgames/Tests/1284086.pgn
Normal file
22
chessgames/Tests/1284086.pgn
Normal file
@@ -0,0 +1,22 @@
|
||||
[Event "Alicante"]
|
||||
[Site "Spain"]
|
||||
[Date "1992.??.??"]
|
||||
[EventDate "?"]
|
||||
[Round "7"]
|
||||
[Result "1/2-1/2"]
|
||||
[White "Stephen Boyd"]
|
||||
[Black "Torbjorn Glimbrant"]
|
||||
[ECO "C49"]
|
||||
[WhiteElo "2265"]
|
||||
[BlackElo "2235"]
|
||||
[PlyCount "91"]
|
||||
|
||||
1.e4 e5 2.Nf3 Nc6 3.Nc3 Nf6 4.Bb5 Bb4 5.O-O O-O 6.d3 d6 7.Bg5
|
||||
Bxc3 8.bxc3 Qe7 9.Re1 Nd8 10.d4 h6 11.Bc1 a6 12.Bd3 Bg4 13.h3
|
||||
Bd7 14.a4 a5 15.Nh4 Nc6 16.Nf5 Bxf5 17.exf5 Qd7 18.g4 exd4
|
||||
19.cxd4 Nxd4 20.Bb2 c5 21.Bxd4 cxd4 22.Bb5 Qc7 23.Qxd4 d5
|
||||
24.Re2 Rad8 25.Rae1 Rd6 26.Re7 Qxc2 27.Rxb7 Ne4 28.Re2 Qc1+
|
||||
29.Kg2 Qc8 30.Re7 Qd8 31.Qa7 Nf6 32.Rc7 d4 33.Ree7 d3 34.Rxf7
|
||||
Rxf7 35.Rxf7 d2 36.Rxg7+ Kh8 37.Be2 d1=Q 38.Bxd1 Rxd1 39.Rg6
|
||||
Qd5+ 40.Kg3 Rd3+ 41.Kh4 Rxh3+ 42.Kxh3 Qh1+ 43.Kg3 Nh5+ 44.gxh5
|
||||
Qf3+ 45.Kh2 Qg2+ 46.Kxg2 1/2-1/2
|
21
chessgames/Tests/1348060.pgn
Normal file
21
chessgames/Tests/1348060.pgn
Normal file
@@ -0,0 +1,21 @@
|
||||
[Event "Norwegian Championship"]
|
||||
[Site "Sandnes NOR"]
|
||||
[Date "2005.07.05"]
|
||||
[EventDate "2005.07.??"]
|
||||
[Round "5"]
|
||||
[Result "1-0"]
|
||||
[White "Magnus Carlsen"]
|
||||
[Black "Geir Sune Tallaksen Ostmoe"]
|
||||
[ECO "E15"]
|
||||
[WhiteElo "2528"]
|
||||
[BlackElo "2349"]
|
||||
[PlyCount "73"]
|
||||
|
||||
1. Nf3 Nf6 2. c4 e6 3. d4 b6 4. g3 Ba6 5. b3 b5 6. cxb5 Bxb5
|
||||
7. Bg2 d5 8. O-O Nbd7 9. Nc3 Ba6 10. Re1 Bd6 11. Bb2 O-O
|
||||
12. e4 Nxe4 13. Nxe4 dxe4 14. Rxe4 Bb7 15. Rh4 Be7 16. Rh3 Nf6
|
||||
17. Qe2 Bd5 18. Re1 Qb8 19. Ne5 Qb7 20. Bxd5 Qxd5 21. Qc2 c5
|
||||
22. Ng4 h6 23. Re5 Qf3 24. Nxh6+ gxh6 25. Rxh6 Kg7 26. Rg5+
|
||||
Kxh6 27. Bc1 cxd4 28. Rg4+ Qe3 29. Rh4+ Nh5 30. Rxh5+ Kxh5
|
||||
31. Qh7+ Kg4 32. fxe3 Rac8 33. Kg2 Rxc1 34. h3+ Kg5 35. Qg7+
|
||||
Kf5 36. g4+ Ke4 37. Qxd4# 1-0
|
31
chessgames/Tests/1427255.pgn
Normal file
31
chessgames/Tests/1427255.pgn
Normal file
@@ -0,0 +1,31 @@
|
||||
[Event "Youth - Experience"]
|
||||
[Site "Amsterdam NED"]
|
||||
[Date "2006.08.27"]
|
||||
[EventDate "2006.08.19"]
|
||||
[Round "8"]
|
||||
[Result "1/2-1/2"]
|
||||
[White "Ulf Andersson"]
|
||||
[Black "Daniel Stellwagen"]
|
||||
[ECO "A04"]
|
||||
[WhiteElo "2542"]
|
||||
[BlackElo "2575"]
|
||||
[PlyCount "175"]
|
||||
|
||||
1. Nf3 f5 2. d4 g6 3. g3 Bg7 4. Bg2 Nf6 5. O-O O-O 6. c4 d6
|
||||
7. Nc3 Qe8 8. d5 a5 9. Nd4 Na6 10. e4 fxe4 11. Nxe4 Nxe4
|
||||
12. Bxe4 Bh3 13. Re1 Nc5 14. Bh1 Qf7 15. Be3 Rae8 16. Qd2 b6
|
||||
17. b3 Kh8 18. Rad1 e5 19. dxe6 Nxe6 20. Bd5 Nxd4 21. Bxd4 Qd7
|
||||
22. a3 Bxd4 23. Qxd4+ Qg7 24. Qxg7+ Kxg7 25. Bc6 Rxe1+
|
||||
26. Rxe1 g5 27. f3 Bf5 28. Kf2 Kf6 29. b4 axb4 30. axb4 Be6
|
||||
31. Re4 Bf5 32. Rd4 Rf7 33. b5 Re7 34. Bd5 Be6 35. f4 Bxd5
|
||||
36. fxg5+ Kxg5 37. Rxd5+ Kg6 38. Kf3 Re1 39. h4 h5 40. Rg5+
|
||||
Kh6 41. g4 hxg4+ 42. Rxg4 Re5 43. Rd4 Rc5 44. Ke4 Kg6 45. Kd3
|
||||
Rh5 46. Rg4+ Kf6 47. Kd4 Ke6 48. Re4+ Kf6 49. Rg4 Ke6 50. Rf4
|
||||
Ke7 51. Ke4 Re5+ 52. Kf3 d5 53. Rd4 Re1 54. Rxd5 Rc1 55. Rd4
|
||||
Kf6 56. Ke4 Ke6 57. Kd3 Rd1+ 58. Kc3 Rc1+ 59. Kd2 Rh1 60. Re4+
|
||||
Kf6 61. Ke3 Rc1 62. Rg4 Kf5 63. Rg5+ Kf6 64. Kd4 Rh1 65. Rg4
|
||||
Ke6 66. Ke4 Re1+ 67. Kf3 Rc1 68. Ke3 Kf5 69. Rd4 Ke5 70. Rd5+
|
||||
Ke6 71. Kd3 Rd1+ 72. Ke4 Rh1 73. h5 Rh4+ 74. Kd3 Rh3+ 75. Kd4
|
||||
Rh4+ 76. Kc3 Rh3+ 77. Kb4 Rg3 78. Rd8 Rh3 79. Rh8 Kd7 80. h6
|
||||
c5+ 81. bxc6+ Kxc6 82. Rh7 Rh4 83. Kb3 Kc5 84. Rc7+ Kd6
|
||||
85. Rh7 Kc5 86. Rc7+ Kd6 87. Rb7 Kc6 88. Rh7 1/2-1/2
|
29
chessgames/Tests/1482551.pgn
Normal file
29
chessgames/Tests/1482551.pgn
Normal file
@@ -0,0 +1,29 @@
|
||||
[Event "Gibraltar Chess Festival"]
|
||||
[Site "Gibraltar ENG"]
|
||||
[Date "2008.01.23"]
|
||||
[EventDate "2008.01.22"]
|
||||
[Round "2"]
|
||||
[Result "1-0"]
|
||||
[White "Tim Jaksland"]
|
||||
[Black "Line Jin Jorgensen"]
|
||||
[ECO "C01"]
|
||||
[WhiteElo "2294"]
|
||||
[BlackElo "1867"]
|
||||
[PlyCount "149"]
|
||||
|
||||
1. e4 e6 2. d4 d5 3. exd5 exd5 4. Nf3 Nf6 5. Bd3 Bd6 6. O-O
|
||||
O-O 7. c4 c6 8. Nc3 Bg4 9. h3 Bh5 10. Re1 dxc4 11. Bxc4 Qc7
|
||||
12. g4 Bg6 13. Ne5 Nfd7 14. f4 Nxe5 15. dxe5 Bc5+ 16. Kg2 h6
|
||||
17. f5 Bh7 18. Qf3 Kh8 19. Bf4 b5 20. Bb3 Qb6 21. Rad1 a5
|
||||
22. a4 Ra7 23. Re2 b4 24. Ne4 Bd4 25. Rxd4 Qxd4 26. Rd2 Qb6
|
||||
27. Be3 Qc7 28. Bc5 Nd7 29. Rxd7 Qxd7 30. Bxf8 Qd4 31. Bc5
|
||||
Qxb2+ 32. Qf2 Qxf2+ 33. Kxf2 Rd7 34. Nd6 Bg8 35. Ke3 Re7
|
||||
36. Kf4 Rxe5 37. Kxe5 f6+ 38. Kd4 Bxb3 39. Bb6 Bxa4 40. Bxa5
|
||||
h5 41. gxh5 Bd1 42. h6 b3 43. hxg7+ Kxg7 44. Bc3 Kh6 45. Ke4
|
||||
Kh5 46. Bxf6 b2 47. Bxb2 Kh4 48. f6 Bb3 49. Ke5 Kxh3 50. f7
|
||||
Bxf7 51. Nxf7 c5 52. Nd6 c4 53. Kf4 c3 54. Bxc3 Kg2 55. Ne4
|
||||
Kh2 56. Kf3 Kg1 57. Nf2 Kh2 58. Be5+ Kg1 59. Bd6 Kf1 60. Bh2
|
||||
Ke1 61. Ne4 Kf1 62. Nd2+ Ke1 63. Ke3 Kd1 64. Kd3 Ke1 65. Bg3+
|
||||
Kd1 66. Bf2 Kc1 67. Nc4 Kd1 68. Nb2+ Kc1 69. Kc3 Kb1 70. Kb3
|
||||
Ka1 71. Be3 Kb1 72. Bf4 Ka1 73. Nc4 Kb1 74. Na3+ Ka1 75. Be5+
|
||||
1-0
|
18
chessgames/Tests/1588906.pgn
Normal file
18
chessgames/Tests/1588906.pgn
Normal file
@@ -0,0 +1,18 @@
|
||||
[Event "BCF-ch 87th"]
|
||||
[Site "Street ENG"]
|
||||
[Date "2000.08.09"]
|
||||
[EventDate "2000.07.31"]
|
||||
[Round "9"]
|
||||
[Result "0-1"]
|
||||
[White "Jack Rudd"]
|
||||
[Black "Martin Simons"]
|
||||
[ECO "B01"]
|
||||
[WhiteElo "2176"]
|
||||
[BlackElo "2226"]
|
||||
[PlyCount "40"]
|
||||
|
||||
1. e4 d5 2. exd5 Nf6 3. c4 e6 4. dxe6 Bxe6 5. d4 Bb4+ 6. Bd2
|
||||
Bxd2+ 7. Qxd2 Qe7 8. Qe2 Nc6 9. Nf3 O-O-O 10. d5 Rhe8 11. Kd1
|
||||
Nxd5 12. cxd5 Bxd5 13. Nfd2 Qf6 14. Qd3 Bxg2 15. Qg3 Bxh1
|
||||
16. Nc3 Bf3+ 17. Kc1 Re1+ 18. Kc2 Nd4+ 19. Kd3 Nb3+ 20. Kc2
|
||||
Nxa1# 0-1
|
21
chessgames/Tests/1775611.pgn
Normal file
21
chessgames/Tests/1775611.pgn
Normal file
@@ -0,0 +1,21 @@
|
||||
[Event "Isle of Man Masters"]
|
||||
[Site "Douglas IMN"]
|
||||
[Date "2014.10.11"]
|
||||
[EventDate "2014.10.04"]
|
||||
[Round "8.2"]
|
||||
[Result "0-1"]
|
||||
[White "Gabriel Sargissian"]
|
||||
[Black "Nigel Short"]
|
||||
[ECO "A70"]
|
||||
[WhiteElo "2690"]
|
||||
[BlackElo "2646"]
|
||||
[PlyCount "78"]
|
||||
|
||||
1. d4 Nf6 2. c4 e6 3. Nf3 c5 4. d5 exd5 5. cxd5 d6 6. Nc3 g6
|
||||
7. Bf4 a6 8. a4 Bg7 9. h3 O-O 10. e3 Ne8 11. Be2 Nd7 12. O-O
|
||||
Rb8 13. Nd2 Ne5 14. a5 f5 15. Bg3 Bd7 16. Qb3 b5 17. axb6 Rxb6
|
||||
18. Qc2 Bb5 19. Nxb5 axb5 20. Nb3 g5 21. Na5 f4 22. Bh2 Nc7
|
||||
23. Rfd1 Kh8 24. Qe4 Qf6 25. exf4 gxf4 26. Nb3 Na6 27. Nd2 c4
|
||||
28. Qb1 Nc5 29. Ne4 Nxe4 30. Qxe4 Rb7 31. Ra5 Nd7 32. b4 cxb3
|
||||
33. Bd3 Qh6 34. Qb4 Nc5 35. Bb1 Be5 36. Rxb5 Rg7 37. Be4 Nxe4
|
||||
38. Qxe4 Qxh3 39. Kh1 Qh5 0-1
|
19
chessgames/Tests/1799484.pgn
Normal file
19
chessgames/Tests/1799484.pgn
Normal file
@@ -0,0 +1,19 @@
|
||||
[Event "Russian Championship Superfinal"]
|
||||
[Site "Chita RUS"]
|
||||
[Date "2015.08.12"]
|
||||
[EventDate "2015.08.09"]
|
||||
[Round "4"]
|
||||
[Result "0-1"]
|
||||
[White "Peter Svidler"]
|
||||
[Black "Denis Khismatullin"]
|
||||
[ECO "B91"]
|
||||
[WhiteElo "2739"]
|
||||
[BlackElo "2642"]
|
||||
[PlyCount "58"]
|
||||
|
||||
1. e4 c5 2. Nc3 a6 3. Nge2 d6 4. g3 g6 5. d4 cxd4 6. Nxd4 Bg7
|
||||
7. Bg2 Nf6 8. b3 O-O 9. Bb2 Bd7 10. Qd2 Nc6 11. Nde2 b5
|
||||
12. O-O-O Ng4 13. Rdf1 Qa5 14. h3 Nf6 15. Kb1 b4 16. Nd1 Qc7
|
||||
17. Ne3 a5 18. f4 a4 19. e5 dxe5 20. fxe5 Nxe5 21. Bxa8 Rxa8
|
||||
22. Rf4 axb3 23. axb3 Qa7 24. Nd4 Nh5 25. Nd5 Bc6 26. Nxc6
|
||||
Qa2+ 27. Kc1 Qa1+ 28. Bxa1 Rxa1+ 29. Kb2 Nc4# 0-1
|
12
chessgames/save_games/20250116 - E gegen F - Runde 2.PGN
Normal file
12
chessgames/save_games/20250116 - E gegen F - Runde 2.PGN
Normal file
@@ -0,0 +1,12 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "2"]
|
||||
[White "E"]
|
||||
[Black "F"]
|
||||
[PlyCount "7"]
|
||||
[Result "*"]
|
||||
|
||||
|
||||
1. e3 e5 2. e4 f5 3. f3 g5
|
||||
4. g4 *
|
11
chessgames/save_games/20250116 - F gegen E - Runde 1
Normal file
11
chessgames/save_games/20250116 - F gegen E - Runde 1
Normal file
@@ -0,0 +1,11 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "1"]
|
||||
[White "F"]
|
||||
[Black "E"]
|
||||
[PlyCount "4"]
|
||||
[Result "*"]
|
||||
|
||||
|
||||
1. e3 e5 2. e4 f5 *
|
10
chessgames/save_games/20250116 - F gegen E - Runde 1.PGN
Normal file
10
chessgames/save_games/20250116 - F gegen E - Runde 1.PGN
Normal file
@@ -0,0 +1,10 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "1"]
|
||||
[White "F"]
|
||||
[Black "E"]
|
||||
[PlyCount "0"]
|
||||
[Result "*"]
|
||||
|
||||
*
|
@@ -0,0 +1,9 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "1"]
|
||||
[White "Player 1"]
|
||||
[Black "Player 2"]
|
||||
[PlyCount "0"]
|
||||
[Result "*"]
|
||||
*
|
@@ -0,0 +1,11 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "1"]
|
||||
[White "Player 2"]
|
||||
[Black "Player 1"]
|
||||
[PlyCount "3"]
|
||||
[Result "*"]
|
||||
|
||||
|
||||
1. e3 e6 2. f4 *
|
@@ -0,0 +1,11 @@
|
||||
[Event "Private Game"]
|
||||
[Site "Horb am Neckar, Germany"]
|
||||
[Date "2025.01.16"]
|
||||
[Round "1"]
|
||||
[White "Sebro"]
|
||||
[Black "Fabian"]
|
||||
[PlyCount "1"]
|
||||
[Result "*"]
|
||||
|
||||
|
||||
1. e3 *
|
194
main.cpp
194
main.cpp
@@ -1,178 +1,38 @@
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "Player/Player.hpp"
|
||||
#include "ChessPieces/ChessPiece.hpp"
|
||||
#include "Chessboard/Chessboard.hpp"
|
||||
#include "Chessboard/ChessboardVisualizerText.hpp"
|
||||
#include "Chessboard/ChessboardVisualizerGraphic.hpp"
|
||||
#include "Visualizer/BaseVisualizer.hpp"
|
||||
#include "Visualizer/StartMenuVisualizer.hpp"
|
||||
#include "Visualizer/HistorieVisualizer.hpp"
|
||||
#include "Visualizer/ChessboardVisualizer.hpp"
|
||||
#include "Visualizer/CommandMenuVisualizer.hpp"
|
||||
#include "Visualizer/PlayingViewVisualizer.hpp"
|
||||
#include "Visualizer/InstructionsVisualizer.hpp"
|
||||
#endif
|
||||
|
||||
#include "MenuController.hpp"
|
||||
#include "./Visualizer/StartMenuVisualizer.hpp"
|
||||
#include "./Visualizer/BaseVisualizer.hpp"
|
||||
#include "./Visualizer/PlaySelectVisualizer.hpp"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <locale>
|
||||
|
||||
void HandleThirdOption() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
InstructionsVisualizer instructions = InstructionsVisualizer();
|
||||
instructions.DisplayElement();
|
||||
std::cout << "\x1B[u";
|
||||
std::cin;
|
||||
}
|
||||
|
||||
void HandleCommandOptions(const std::string& command) {
|
||||
if (command == "1") {
|
||||
HandleThirdOption();
|
||||
} else if (command == "2") {
|
||||
// ToDo: Save implementieren
|
||||
} else if (command == "3") {
|
||||
// ToDo: Exit implementieren -> Möglichkeit noch zu speichern oder einfach speichern?
|
||||
} else if (command == "8") {
|
||||
// ToDo: Spiel beenden -> Gewinn an anderen gegeben
|
||||
} else if (command == "9") {
|
||||
// ToDo: Draw anbieten -> Anfrage mit Annahme/Ablehnen an anderen Spieler schicken
|
||||
}
|
||||
}
|
||||
|
||||
std::string ExtractAfterDollar(const std::string& userInput) {
|
||||
// Überprüfen, ob der String mit '$' beginnt
|
||||
if (!userInput.empty() && userInput[0] == '$') {
|
||||
return userInput.substr(1); // Rückgabe des Teils nach '$'
|
||||
}
|
||||
return ""; // Leerer String, wenn kein '$' am Anfang
|
||||
}
|
||||
|
||||
void HandleFirstOption() {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
Player* playerA = new Player("Player 1");
|
||||
Player* playerB = new Player("Player 2");
|
||||
|
||||
Chessboard chessboard = Chessboard();
|
||||
chessboard.SetPlayers(playerA, playerB);
|
||||
|
||||
chessboard.InitializeStartBoard();
|
||||
|
||||
PlayingViewVisualizer playView = PlayingViewVisualizer(&chessboard, 4, 12);
|
||||
|
||||
while (chessboard.IsCheckmate() == false) {
|
||||
std::string input;
|
||||
|
||||
playView.DisplayElement();
|
||||
|
||||
std::cout << "\x1B[u";
|
||||
std::cin >> input;
|
||||
|
||||
std::string command = ExtractAfterDollar(input);
|
||||
|
||||
while (command != "3") {
|
||||
if (command != "") {
|
||||
HandleCommandOptions(command);
|
||||
break;
|
||||
} else {
|
||||
//ToDo: Valide Züge annehmen
|
||||
chessboard.MoveChessPiece(input);
|
||||
}
|
||||
// ToDo: Nicht valide Eingabe melden -> Unterscheidung was falsch?
|
||||
}
|
||||
break;
|
||||
}
|
||||
std::cout << "Game is over! - " << chessboard.GetOpponentPlayer()->GetName() << " has won the game!" << std::endl;
|
||||
}
|
||||
|
||||
void HandleSecondOption() {}
|
||||
|
||||
int main() {
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
BaseVisualizer::ClearTerminal();
|
||||
StartMenuVisualizer startMenu(3);
|
||||
MenuController menuController;
|
||||
StartMenuVisualizer::StartMenuOption optionStartMenu = StartMenuVisualizer::StartMenuOption::None;
|
||||
|
||||
StartMenuVisualizer startMenu = StartMenuVisualizer(3);
|
||||
int choice = -1;
|
||||
|
||||
while (startMenu.GetSelectedOption() != 0) {
|
||||
BaseVisualizer::ClearTerminal();
|
||||
startMenu.DisplayElement1();
|
||||
|
||||
if (startMenu.GetSelectedOption() == 1) {
|
||||
HandleFirstOption();
|
||||
} else if (startMenu.GetSelectedOption() == 2) {
|
||||
HandleSecondOption();
|
||||
} else if (startMenu.GetSelectedOption() == 3) {
|
||||
HandleThirdOption();
|
||||
do {
|
||||
switch (optionStartMenu = startMenu.ShowMenu()) {
|
||||
case StartMenuVisualizer::StartMenuOption::NewGame:
|
||||
menuController.HandleFirstOption();
|
||||
break;
|
||||
case StartMenuVisualizer::StartMenuOption::LoadGame:
|
||||
menuController.HandleSecondOption();
|
||||
break;
|
||||
case StartMenuVisualizer::StartMenuOption::Instructions:
|
||||
menuController.HandleThirdOption();
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//CommandMenuVisualizer commandMenu = CommandMenuVisualizer(2);
|
||||
//commandMenu.DisplayElement();
|
||||
//HistorieVisualizer historie = HistorieVisualizer(15, 2, "Player 1", "Player 2");
|
||||
//historie.DisplayElement();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*if () {
|
||||
Player* playerA = new Player("Player 1");
|
||||
Player* playerB = new Player("Player 2");
|
||||
|
||||
Chessboard chessboard = Chessboard();
|
||||
chessboard.SetPlayers(playerA, playerB);
|
||||
|
||||
chessboard.InitializeStartBoard();
|
||||
|
||||
// Jetzt kann man Moves machen. Nach jedem Move müssen die ChessPieces aktualisiert werden.
|
||||
chessboard.UpdateChessPieces();
|
||||
|
||||
//ChessboardVisualizerText* visualizer = new ChessboardVisualizerText();
|
||||
ChessboardVisualizer visualizer(&chessboard, 2);
|
||||
|
||||
|
||||
}*/
|
||||
//}
|
||||
|
||||
/*std::cout << "Spieler A: ";
|
||||
std::string namePlayerA;
|
||||
getline(std::cin, namePlayerA);
|
||||
std::cout << "Spieler B: ";
|
||||
std::string namePlayerB;
|
||||
getline(std::cin, namePlayerB);
|
||||
|
||||
Player* playerA = new Player("1");
|
||||
Player* playerB = new Player("2");*/
|
||||
|
||||
|
||||
} while (optionStartMenu != StartMenuVisualizer::StartMenuOption::Exit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
std::vector<std::vector<ChessPiece>> chessmatrix;
|
||||
|
||||
Chessboard chessboard;
|
||||
|
||||
if (argc == 2) {
|
||||
std::cout << "Spielstand" << std::endl;
|
||||
chessboard.loadBoard(std::string(argv[1]));
|
||||
} else {
|
||||
chessboard.setBoard(chessboard.getStartBoard());
|
||||
}
|
||||
|
||||
//chessboard.init();
|
||||
chessboard.draw();
|
||||
|
||||
while (true) {
|
||||
std::string move;
|
||||
std::cout << "Move [" << (chessboard.getTurnOrder() ? "white" : "black") << "]: ";
|
||||
std::cin >> move;
|
||||
|
||||
chessboard.move(move);
|
||||
chessboard.saveBoard();
|
||||
|
||||
}
|
||||
*/
|
||||
|
10
makefile
Normal file
10
makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
all:
|
||||
g++ -std=c++17 -o chess main.cpp MenuController.cpp ChessPieces/*.cpp Chessboard/*.cpp Player/*.cpp Visualizer/*.cpp
|
||||
|
||||
run:
|
||||
./chess
|
||||
|
||||
clean:
|
||||
rm -f main.exe
|
||||
rm -f chess.exe
|
||||
rm -f chess
|
2
run.ps1
Normal file
2
run.ps1
Normal file
@@ -0,0 +1,2 @@
|
||||
& "g++" -std=c++17 -o chess main.cpp MenuController.cpp ChessPieces/*.cpp Chessboard/*.cpp Player/*.cpp Visualizer/*.cpp
|
||||
./chess.exe
|
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"saves": [
|
||||
[
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
[
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[]
|
||||
],
|
||||
[
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[]
|
||||
]
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user