mirror of
https://github.com/Vale54321/schafkopf-bot.git
synced 2025-12-15 11:19:33 +01:00
Spielablauf (#11)
* added Spielablauf and added various things like Card classes etc. Co-authored-by: Tobias <tibistruppi.te@gmail.com>
This commit is contained in:
committed by
GitHub
parent
da81e7bac0
commit
1376fe645a
21
.github/workflows/maven.yml
vendored
Normal file
21
.github/workflows/maven.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
cache: maven
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
File diff suppressed because one or more lines are too long
598
intellij-java-google-style.xml
Normal file
598
intellij-java-google-style.xml
Normal file
@@ -0,0 +1,598 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<code_scheme name="GoogleStyle">
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="USE_CUSTOM_SETTINGS" value="true"/>
|
||||
<option name="LAYOUT_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false"/>
|
||||
</value>
|
||||
</option>
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<JSCodeStyleSettings>
|
||||
<option name="INDENT_CHAINED_CALLS" value="false"/>
|
||||
</JSCodeStyleSettings>
|
||||
<Objective-C>
|
||||
<option name="INDENT_NAMESPACE_MEMBERS" value="0"/>
|
||||
<option name="INDENT_C_STRUCT_MEMBERS" value="2"/>
|
||||
<option name="INDENT_CLASS_MEMBERS" value="2"/>
|
||||
<option name="INDENT_VISIBILITY_KEYWORDS" value="1"/>
|
||||
<option name="INDENT_INSIDE_CODE_BLOCK" value="2"/>
|
||||
<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true"/>
|
||||
<option name="FUNCTION_PARAMETERS_WRAP" value="5"/>
|
||||
<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5"/>
|
||||
<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5"/>
|
||||
<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true"/>
|
||||
<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false"/>
|
||||
<option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false"/>
|
||||
</Objective-C>
|
||||
<Objective-C-extensions>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod"/>
|
||||
</class>
|
||||
<extensions>
|
||||
<pair header="h" source="cc"/>
|
||||
<pair header="h" source="c"/>
|
||||
</extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl"/>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function"/>
|
||||
</file>
|
||||
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK"/>
|
||||
<option name="RELEASE_STYLE" value="IVAR"/>
|
||||
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE"/>
|
||||
</Objective-C-extensions>
|
||||
<Python>
|
||||
<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true"/>
|
||||
</Python>
|
||||
<TypeScriptCodeStyleSettings>
|
||||
<option name="INDENT_CHAINED_CALLS" value="false"/>
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_ALIGN_ATTRIBUTES" value="false"/>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
|
||||
</XML>
|
||||
<codeStyleSettings language="CSS">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="ECMA Script Level 4">
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="EXTENDS_LIST_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_RESOURCES" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="EXTENDS_LIST_WRAP" value="1"/>
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="WRAP_COMMENTS" value="true"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
<option name="RIGHT_MARGIN" value="80"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PROTO">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
<option name="RIGHT_MARGIN" value="80"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="protobuf">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
<option name="RIGHT_MARGIN" value="80"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Python">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
<option name="RIGHT_MARGIN" value="80"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SASS">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SCSS">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="TypeScript">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:.*Style</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_width</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_height</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_weight</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_margin</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginTop</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginBottom</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginStart</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginEnd</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginLeft</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginRight</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_.*</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:padding</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingTop</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingBottom</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingStart</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingEnd</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingLeft</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingRight</NAME>
|
||||
<XML_ATTRIBUTE/>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res-auto</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="ObjectiveC">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
</indentOptions>
|
||||
<option name="RIGHT_MARGIN" value="80"/>
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
|
||||
<option name="BLANK_LINES_BEFORE_IMPORTS" value="0"/>
|
||||
<option name="BLANK_LINES_AFTER_IMPORTS" value="0"/>
|
||||
<option name="BLANK_LINES_AROUND_CLASS" value="0"/>
|
||||
<option name="BLANK_LINES_AROUND_METHOD" value="0"/>
|
||||
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0"/>
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ASSIGNMENT_WRAP" value="1"/>
|
||||
</codeStyleSettings>
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2"/>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
<option name="USE_TAB_CHARACTER" value="false"/>
|
||||
<option name="SMART_TABS" value="false"/>
|
||||
<option name="LABEL_INDENT_SIZE" value="0"/>
|
||||
<option name="LABEL_INDENT_ABSOLUTE" value="false"/>
|
||||
<option name="USE_RELATIVE_INDENTS" value="false"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999"/>
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value/>
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<emptyLine/>
|
||||
<package name="" static="true" withSubpackages="true"/>
|
||||
<package name="" static="false" withSubpackages="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="RIGHT_MARGIN" value="100"/>
|
||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
|
||||
<option name="JD_P_AT_EMPTY_LINES" value="false"/>
|
||||
<option name="JD_KEEP_EMPTY_PARAMETER" value="false"/>
|
||||
<option name="JD_KEEP_EMPTY_EXCEPTION" value="false"/>
|
||||
<option name="JD_KEEP_EMPTY_RETURN" value="false"/>
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="0"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="EXTENDS_LIST_WRAP" value="1"/>
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
|
||||
<option name="FOR_STATEMENT_WRAP" value="1"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="WRAP_COMMENTS" value="true"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
|
||||
</code_scheme>
|
||||
@@ -1,9 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pn532</groupId>
|
||||
<project
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<artifactId>pn532-sdk</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<description>POM was created from install:install-file</description>
|
||||
<groupId>pn532</groupId>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<version>1.0.2</version>
|
||||
</project>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>pn532</groupId>
|
||||
<artifactId>pn532-sdk</artifactId>
|
||||
<groupId>pn532</groupId>
|
||||
<versioning>
|
||||
<lastUpdated>20231116111447</lastUpdated>
|
||||
<release>1.0.2</release>
|
||||
<versions>
|
||||
<version>1.0.2</version>
|
||||
</versions>
|
||||
<lastUpdated>20231116111447</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
||||
312
pom.xml
312
pom.xml
@@ -1,165 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<artifactId>schafkopf-backend-java</artifactId>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>schafkopf-backend-java</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<build>
|
||||
<finalName>schafkopf-backend-build</finalName>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- DEPENDENCIES VERSIONS -->
|
||||
<slf4j.version>1.7.32</slf4j.version>
|
||||
<pi4j.version>2.4.0</pi4j.version>
|
||||
<maven-compiler.version>3.5.1</maven-compiler.version>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<configuration>
|
||||
<configLocation>google_checks.xml</configLocation>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<version>3.3.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.schafkopf.BackendServer</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<version>3.3.0</version>
|
||||
</plugin>
|
||||
|
||||
</properties>
|
||||
<build>
|
||||
<finalName>schafkopf-backend-build</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<configuration>
|
||||
<configLocation>google_checks.xml</configLocation>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.example.BackendServer</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<showWarnings>true</showWarnings>
|
||||
<verbose>false</verbose>
|
||||
</configuration>
|
||||
<version>3.11.0</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<showWarnings>true</showWarnings>
|
||||
<verbose>false</verbose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
</transformers>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<version>3.5.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<!-- To write basic websockets against -->
|
||||
<dependency>
|
||||
<artifactId>websocket-jetty-api</artifactId>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<!-- To run websockets in embedded server -->
|
||||
<dependency>
|
||||
<artifactId>websocket-jetty-server</artifactId>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<!-- To run websockets client -->
|
||||
<dependency>
|
||||
<artifactId>websocket-jetty-client</artifactId>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>gson</artifactId>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>dotenv-java</artifactId>
|
||||
<groupId>io.github.cdimascio</groupId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
</transformers>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>in-project</id>
|
||||
<name>In Project Repo</name>
|
||||
<url>file://${project.basedir}/lib</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<!-- include Pi4J Core -->
|
||||
<dependency>
|
||||
<artifactId>pi4j-core</artifactId>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<version>${pi4j.version}</version> <!-- Use the latest version available -->
|
||||
</dependency>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<!-- To write basic websockets against -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-jetty-api</artifactId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<!-- To run websockets in embedded server -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-jetty-server</artifactId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<!-- To run websockets client -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-jetty-client</artifactId>
|
||||
<version>11.0.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.cdimascio</groupId>
|
||||
<artifactId>dotenv-java</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- include Pi4J Core -->
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-core</artifactId>
|
||||
<version>${pi4j.version}</version> <!-- Use the latest version available -->
|
||||
</dependency>
|
||||
|
||||
<!-- include Pi4J Plugins (Platforms and I/O Providers) -->
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-plugin-raspberrypi</artifactId>
|
||||
<version>${pi4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<artifactId>pi4j-plugin-pigpio</artifactId>
|
||||
<version>${pi4j.version}</version>
|
||||
</dependency>
|
||||
<!-- include Pi4J Plugins (Platforms and I/O Providers) -->
|
||||
<dependency>
|
||||
<artifactId>pi4j-plugin-raspberrypi</artifactId>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<version>${pi4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>pi4j-plugin-pigpio</artifactId>
|
||||
<groupId>com.pi4j</groupId>
|
||||
<version>${pi4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>pn532</groupId>
|
||||
<artifactId>pn532-sdk</artifactId>
|
||||
<version>1.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<artifactId>pn532-sdk</artifactId>
|
||||
<groupId>pn532</groupId>
|
||||
<version>1.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<groupId>org.example</groupId>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
<maven-compiler.version>3.5.1</maven-compiler.version>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<!-- DEPENDENCIES VERSIONS -->
|
||||
<pi4j.version>2.4.0</pi4j.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<slf4j.version>1.7.32</slf4j.version>
|
||||
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>in-project</id>
|
||||
<name>In Project Repo</name>
|
||||
<url>file://${project.basedir}/lib</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</project>
|
||||
@@ -1,164 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlets.CrossOriginFilter;
|
||||
import io.github.cdimascio.dotenv.Dotenv;
|
||||
|
||||
public class BackendServer
|
||||
{
|
||||
private List<FrontendEndpoint> frontendEndpoints = new ArrayList<>();
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
BackendServer server = new BackendServer();
|
||||
server.setPort(8080);
|
||||
server.start();
|
||||
server.join();
|
||||
}
|
||||
|
||||
private final Server server;
|
||||
private final ServerConnector connector;
|
||||
|
||||
private final Schafkopf schafkopfGame;
|
||||
private final KartenLeser nfcLeser;
|
||||
private CountDownLatch nfcLatch = new CountDownLatch(1);
|
||||
|
||||
private Boolean readingMode = false;
|
||||
private String uidString = "";
|
||||
|
||||
public BackendServer()
|
||||
{
|
||||
Dotenv dotenv = Dotenv.configure().directory("./").load();
|
||||
server = new Server();
|
||||
InetSocketAddress address = new InetSocketAddress(dotenv.get("VITE_APP_WEBSOCKET_IP"), 8080);
|
||||
connector = new ServerConnector(server);
|
||||
connector.setHost(address.getHostName());
|
||||
connector.setPort(address.getPort());
|
||||
server.addConnector(connector);
|
||||
|
||||
schafkopfGame = new Schafkopf(this);
|
||||
nfcLeser = new KartenLeser(this);
|
||||
|
||||
// Setup the basic application "context" for this application at "/"
|
||||
// This is also known as the handler tree (in jetty speak)
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
|
||||
// Configure CORS settings
|
||||
configureCORS(context);
|
||||
|
||||
// Configure specific websocket behavior
|
||||
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
|
||||
{
|
||||
// Configure default max size
|
||||
wsContainer.setMaxTextMessageSize(65535);
|
||||
wsContainer.setIdleTimeout(Duration.ofDays(300000));
|
||||
// Add websockets
|
||||
wsContainer.addMapping("/schafkopf-events/*", new FrontendEndpointCreator(this));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void configureCORS(ServletContextHandler context) {
|
||||
// Enable CORS for all paths
|
||||
FilterHolder cors = context.addFilter(CrossOriginFilter.class, "/*", null);
|
||||
|
||||
// Configure allowed origins, headers, and methods
|
||||
cors.setInitParameter("allowedOrigins", "http://192.168.178.126:5173");
|
||||
cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin");
|
||||
cors.setInitParameter("allowedMethods", "GET,POST,PUT,DELETE,OPTIONS");
|
||||
|
||||
// Add filter mappings
|
||||
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST);
|
||||
context.addFilter(cors, "*", types);
|
||||
}
|
||||
|
||||
public void setPort(int port)
|
||||
{
|
||||
connector.setPort(port);
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
{
|
||||
server.start();
|
||||
}
|
||||
|
||||
public URI getURI()
|
||||
{
|
||||
return server.getURI();
|
||||
}
|
||||
|
||||
public void stop() throws Exception
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException
|
||||
{
|
||||
server.join();
|
||||
}
|
||||
|
||||
public void addFrontendEndpoint(FrontendEndpoint endpoint) {
|
||||
frontendEndpoints.add(endpoint);
|
||||
}
|
||||
|
||||
public void removeFrontendEndpoint(FrontendEndpoint endpoint) {
|
||||
frontendEndpoints.remove(endpoint);
|
||||
}
|
||||
|
||||
public void sendMessageToAllFrontendEndpoints(String message) {
|
||||
for (FrontendEndpoint endpoint : frontendEndpoints) {
|
||||
endpoint.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void startSchafkopfGame() {
|
||||
schafkopfGame.startGame();
|
||||
}
|
||||
|
||||
public void stopSchafkopfGame() {
|
||||
schafkopfGame.stopGame();
|
||||
}
|
||||
|
||||
public void showTrumpf() {
|
||||
schafkopfGame.showTrumpf();
|
||||
}
|
||||
|
||||
public void showFarbe() {
|
||||
schafkopfGame.showFarbe();
|
||||
}
|
||||
public void nfcGelesen(String uidString) {
|
||||
if(this.uidString.equals(uidString)){
|
||||
return;
|
||||
}
|
||||
if(!this.readingMode){
|
||||
return;
|
||||
}
|
||||
|
||||
this.uidString = uidString;
|
||||
nfcLatch.countDown();
|
||||
}
|
||||
|
||||
public String waitForCardScan() throws InterruptedException {
|
||||
this.readingMode = true;
|
||||
nfcLatch.await();
|
||||
this.readingMode = false;
|
||||
nfcLatch = new CountDownLatch(1);
|
||||
return this.uidString;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class FrontendEndpoint extends WebSocketAdapter {
|
||||
private final CountDownLatch closureLatch = new CountDownLatch(1);
|
||||
private BackendServer backendServer;
|
||||
public FrontendEndpoint(BackendServer backendServer) {
|
||||
this.backendServer = backendServer;
|
||||
System.out.println("new FrontendEndpoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session session) {
|
||||
super.onWebSocketConnect(session);
|
||||
String clientIp = session.getRemoteAddress().toString();
|
||||
System.out.println("Endpoint connected from ip: " + clientIp);
|
||||
|
||||
backendServer.addFrontendEndpoint(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(String message) {
|
||||
super.onWebSocketText(message);
|
||||
System.out.println("Received TEXT message:" + message);
|
||||
|
||||
if (message.contains("startsimulation")) {
|
||||
backendServer.startSchafkopfGame();
|
||||
}
|
||||
|
||||
if (message.contains("stopsimulation")) {
|
||||
backendServer.stopSchafkopfGame();
|
||||
}
|
||||
|
||||
if(message.contains("showtrumpf")) {
|
||||
backendServer.showTrumpf();
|
||||
}
|
||||
|
||||
if(message.contains("showfarben")) {
|
||||
backendServer.showFarbe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketClose(int statusCode, String reason) {
|
||||
super.onWebSocketClose(statusCode, reason);
|
||||
|
||||
backendServer.removeFrontendEndpoint(this);
|
||||
|
||||
System.out.println("Socket Closed: [" + statusCode + "] " + reason);
|
||||
closureLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketError(Throwable cause) {
|
||||
super.onWebSocketError(cause);
|
||||
cause.printStackTrace(System.err);
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
try {
|
||||
getRemote().sendString(message);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package org.example;
|
||||
import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
|
||||
|
||||
public class FrontendEndpointCreator implements JettyWebSocketCreator
|
||||
{
|
||||
private BackendServer backendServer;
|
||||
public FrontendEndpointCreator(BackendServer backendServer) {
|
||||
this.backendServer = backendServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(JettyServerUpgradeRequest jettyServerUpgradeRequest, JettyServerUpgradeResponse jettyServerUpgradeResponse)
|
||||
{
|
||||
return new FrontendEndpoint(this.backendServer);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
public class Karte {
|
||||
private String id;
|
||||
private String name;
|
||||
private String farbe;
|
||||
private String symbol;
|
||||
private int punkte;
|
||||
Karte(String id, String name, String farbe, String symbol, int punkte){
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.farbe = farbe;
|
||||
this.symbol = symbol;
|
||||
this.punkte = punkte;
|
||||
}
|
||||
|
||||
public String getId(){
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getFarbe(){
|
||||
return this.farbe;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return this.symbol;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.pi4j.Pi4J;
|
||||
import com.pi4j.io.i2c.I2C;
|
||||
import mk.hsilomedus.pn532.*;
|
||||
import mk.hsilomedus.pn532.Pn532SamThread.Pn532SamThreadListener;
|
||||
|
||||
public final class KartenLeser {
|
||||
|
||||
private static BackendServer server;
|
||||
|
||||
public KartenLeser(BackendServer server){
|
||||
this.server = server;
|
||||
|
||||
new Thread(() -> {
|
||||
|
||||
new KartenListener().run();
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final void main(String[] args) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
private static class KartenListener implements Pn532SamThreadListener {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
Pn532SamThread<I2C> i2cThread = new Pn532SamThread<>(this, new Pn532I2c());
|
||||
|
||||
|
||||
public void run() {
|
||||
Pn532ContextHelper.initialize();
|
||||
i2cThread.start();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closeThread(i2cThread);
|
||||
Pn532ContextHelper.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveMessage(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uidReceived(String displayName, byte[] uid) {
|
||||
server.nfcGelesen(Pn532SamThreadListener.getUidString(uid) );
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void closeThread(Pn532SamThread thread) {
|
||||
if (thread != null && thread.isAlive()) {
|
||||
thread.close();
|
||||
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Error closing thread: " + e.getMessage());
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class KartenUtil {
|
||||
|
||||
public static List<Karte> getKartenByFarbe(List<Karte> karten, String farbe) {
|
||||
List<Karte> result = new ArrayList<>();
|
||||
for (Karte karte : karten) {
|
||||
if (karte.getFarbe().equalsIgnoreCase(farbe)) {
|
||||
result.add(karte);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Karte> getKartenBySymbol(List<Karte> karten, String symbol) {
|
||||
List<Karte> result = new ArrayList<>();
|
||||
for (Karte karte : karten) {
|
||||
if (karte.getSymbol().equalsIgnoreCase(symbol)) {
|
||||
result.add(karte);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Karte> initializeSchafKopfCardDeck() {
|
||||
String[] farben = {"schell", "herz", "blatt", "eichel"};
|
||||
String[] symbole = {"6", "7", "8", "9", "u", "o", "k", "x", "a"};
|
||||
|
||||
int totalCards = farben.length * symbole.length;
|
||||
List<Karte> deck = new ArrayList<>();
|
||||
|
||||
for (String farbe : farben) {
|
||||
for (String symbol : symbole) {
|
||||
String cardId = farbe + "_" + symbol;
|
||||
String cardName = getCardName(farbe, symbol);
|
||||
int wert = switch (symbol) {
|
||||
case "6", "9", "8", "7" -> 0;
|
||||
case "k" -> 4;
|
||||
case "x" -> 10;
|
||||
case "a" -> 11;
|
||||
case "u" -> 2;
|
||||
case "o" -> 3;
|
||||
default -> -1;
|
||||
};
|
||||
deck.add(new Karte(cardId, cardName, farbe, symbol, wert));
|
||||
}
|
||||
}
|
||||
deck.removeAll(KartenUtil.getKartenBySymbol(deck, "6"));
|
||||
return deck;
|
||||
}
|
||||
|
||||
private static String getCardName(String farbe, String symbol) {
|
||||
String cardName = switch (farbe) {
|
||||
case "schell" -> "Schell";
|
||||
case "herz" -> "Herz";
|
||||
case "blatt" -> "Blatt";
|
||||
case "eichel" -> "Eichel";
|
||||
default -> "";
|
||||
};
|
||||
String prefix = switch (symbol) {
|
||||
case "6" -> "6";
|
||||
case "7" -> "7";
|
||||
case "8" -> "8";
|
||||
case "9" -> "9";
|
||||
case "k" -> "König";
|
||||
case "x" -> "10";
|
||||
case "a" -> "Ass";
|
||||
case "u" -> "Unter";
|
||||
case "o" -> "Ober";
|
||||
default -> "";
|
||||
};
|
||||
cardName += " " + prefix;
|
||||
return cardName;
|
||||
}
|
||||
|
||||
public static String getIdOfUid(String uid){
|
||||
switch (uid){
|
||||
case "04A56BB4780000":
|
||||
return "eichel_7";
|
||||
case "04A46BB4780000":
|
||||
return "eichel_8";
|
||||
case "04A26BB4780000":
|
||||
return "eichel_9";
|
||||
case "04A16BB4780000":
|
||||
return "eichel_x";
|
||||
case "049E6BB4780000":
|
||||
return "eichel_k";
|
||||
case "04A86BB4780000":
|
||||
return "eichel_a";
|
||||
case "04A06BB4780000":
|
||||
return "eichel_u";
|
||||
case "049F6BB4780000":
|
||||
return "eichel_o";
|
||||
|
||||
case "04F26BB4780000":
|
||||
return "blatt_7";
|
||||
case "04A76BB4780000":
|
||||
return "blatt_8";
|
||||
case "049B6BB4780000":
|
||||
return "blatt_9";
|
||||
case "04996BB4780000":
|
||||
return "blatt_x";
|
||||
case "041CD2C2126F81":
|
||||
return "blatt_k";
|
||||
case "04A96BB4780000":
|
||||
return "blatt_a";
|
||||
case "049A6BB4780000":
|
||||
return "blatt_u";
|
||||
case "049D6BB4780000":
|
||||
return "blatt_o";
|
||||
|
||||
case "04936BB4780000":
|
||||
return "schell_7";
|
||||
case "04F697C2126F80":
|
||||
return "schell_8";
|
||||
case "04946BB4780000":
|
||||
return "schell_9";
|
||||
case "04956BB4780000":
|
||||
return "schell_x";
|
||||
case "04986BB4780000":
|
||||
return "schell_k";
|
||||
case "04AA6BB4780000":
|
||||
return "schell_a";
|
||||
case "04966BB4780000":
|
||||
return "schell_u";
|
||||
case "04976BB4780000":
|
||||
return "schell_o";
|
||||
|
||||
case "04F36BB4780000":
|
||||
return "herz_7";
|
||||
case "04B06BB4780000":
|
||||
return "herz_8";
|
||||
case "04AF6BB4780000":
|
||||
return "herz_9";
|
||||
case "04AE6BB4780000":
|
||||
return "herz_x";
|
||||
case "04AB6BB4780000":
|
||||
return "herz_k";
|
||||
case "049C6BB4780000":
|
||||
return "herz_a";
|
||||
case "04AD6BB4780000":
|
||||
return "herz_u";
|
||||
case "04AC6BB4780000":
|
||||
return "herz_o";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Karte getKarteById(String id){
|
||||
List<Karte> kartenList = initializeSchafKopfCardDeck();
|
||||
for (Karte karte : kartenList) {
|
||||
if (karte.getId().equalsIgnoreCase(id)) {
|
||||
return karte;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void removeCards(List<Karte> allCards, List<Karte> cardsToRemove) {
|
||||
allCards.removeAll(cardsToRemove);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.example.spielController.GeierSpielController;
|
||||
import org.example.spielController.SoloSpielController;
|
||||
import org.example.spielController.SpielController;
|
||||
import org.example.spielController.WenzSpielController;
|
||||
|
||||
public class Schafkopf {
|
||||
private final Karte[] kartenDeck;
|
||||
private final SpielController spielController = new GeierSpielController( "schell");
|
||||
private final BackendServer server;
|
||||
private boolean gameState = false;
|
||||
|
||||
Schafkopf(BackendServer server) {
|
||||
this.server = server;
|
||||
System.out.println("SchaffKopfGame erstellt");
|
||||
this.kartenDeck = initializeCardDeck();
|
||||
}
|
||||
|
||||
private static String getCardName(String farbe, String symbol) {
|
||||
String cardName = switch (farbe) {
|
||||
case "schell" -> "Schell";
|
||||
case "herz" -> "Herz";
|
||||
case "blatt" -> "Blatt";
|
||||
case "eichel" -> "Eichel";
|
||||
default -> "";
|
||||
};
|
||||
String prefix = switch (symbol) {
|
||||
case "6" -> "6";
|
||||
case "7" -> "7";
|
||||
case "8" -> "8";
|
||||
case "9" -> "9";
|
||||
case "k" -> "König";
|
||||
case "x" -> "10";
|
||||
case "a" -> "Ass";
|
||||
case "u" -> "Unter";
|
||||
case "o" -> "Ober";
|
||||
default -> "";
|
||||
};
|
||||
cardName += " " + prefix;
|
||||
return cardName;
|
||||
}
|
||||
|
||||
public Karte[] initializeCardDeck() {
|
||||
String[] farben = {"schell", "herz", "blatt", "eichel"};
|
||||
String[] symbole = {"6", "7", "8", "9", "k", "x", "a", "u", "o"};
|
||||
|
||||
int totalCards = farben.length * symbole.length;
|
||||
Karte[] Deck = new Karte[totalCards];
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (String farbe : farben) {
|
||||
for (String symbol : symbole) {
|
||||
String cardId = farbe + "_" + symbol;
|
||||
String cardName = getCardName(farbe, symbol);
|
||||
int wert = switch (symbol) {
|
||||
case "6", "9", "8", "7" -> 0;
|
||||
case "k" -> 4;
|
||||
case "x" -> 10;
|
||||
case "a" -> 11;
|
||||
case "u" -> 2;
|
||||
case "o" -> 3;
|
||||
default -> -1;
|
||||
};
|
||||
Deck[index] = new Karte(cardId, cardName, farbe, symbol, wert);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return Deck;
|
||||
}
|
||||
|
||||
public void showTrumpf() {
|
||||
|
||||
Gson gson = new Gson();
|
||||
for (Karte karte : spielController.getTrumpfKarten()) {
|
||||
String karteJson = gson.toJson(karte);
|
||||
server.sendMessageToAllFrontendEndpoints(karteJson);
|
||||
}
|
||||
}
|
||||
|
||||
public void showFarbe() {
|
||||
Gson gson = new Gson();
|
||||
for (Karte karte : spielController.getFarbKarten()) {
|
||||
String karteJson = gson.toJson(karte);
|
||||
server.sendMessageToAllFrontendEndpoints(karteJson);
|
||||
}
|
||||
}
|
||||
|
||||
public void startGame() {
|
||||
if (gameState) {
|
||||
System.out.println("Game already started!");
|
||||
server.sendMessageToAllFrontendEndpoints("Game already started!");
|
||||
} else {
|
||||
gameState = true;
|
||||
System.out.println("Start Game");
|
||||
server.sendMessageToAllFrontendEndpoints("Start Game");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopGame() {
|
||||
if (!gameState) {
|
||||
System.out.println("no active Game!");
|
||||
server.sendMessageToAllFrontendEndpoints("no active Game!");
|
||||
} else {
|
||||
gameState = false;
|
||||
System.out.println("Stop Game");
|
||||
server.sendMessageToAllFrontendEndpoints("Stop Game");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package org.example.spielController;
|
||||
|
||||
import org.example.Karte;
|
||||
import org.example.KartenUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeierSpielController extends SpielController {
|
||||
public GeierSpielController(String farbe) {
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> oberKarten = KartenUtil.getKartenBySymbol(kartenList, "o");
|
||||
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
|
||||
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
|
||||
farbTrumpfKarten.addAll(oberKarten);
|
||||
kartenList.removeAll(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
|
||||
public GeierSpielController() {
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> oberKarten = KartenUtil.getKartenBySymbol(kartenList, "o");
|
||||
|
||||
kartenList.removeAll(oberKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(oberKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.example.spielController;
|
||||
import org.example.Karte;
|
||||
import org.example.KartenUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SauSpielController extends SpielController{
|
||||
|
||||
public SauSpielController(){
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> herzKarten = KartenUtil.getKartenByFarbe(kartenList, "herz");
|
||||
herzKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
|
||||
herzKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
|
||||
|
||||
herzKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
|
||||
herzKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
|
||||
|
||||
kartenList.removeAll(herzKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(herzKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.example.spielController;
|
||||
|
||||
import org.example.Karte;
|
||||
import org.example.KartenUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SoloSpielController extends SpielController {
|
||||
public SoloSpielController(String farbe) {
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
|
||||
|
||||
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
|
||||
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
|
||||
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
|
||||
farbTrumpfKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
|
||||
farbTrumpfKarten.addAll(KartenUtil.getKartenBySymbol(kartenList, "o"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
kartenList.removeAll(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.example.spielController;
|
||||
|
||||
import org.example.Karte;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SpielController {
|
||||
protected List<Karte> trumpfKarten;
|
||||
protected List<Karte> farbKarten;
|
||||
|
||||
|
||||
|
||||
public List<Karte> getTrumpfKarten() {
|
||||
return trumpfKarten;
|
||||
}
|
||||
|
||||
public List<Karte> getFarbKarten() {
|
||||
return farbKarten;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package org.example.spielController;
|
||||
|
||||
import org.example.Karte;
|
||||
import org.example.KartenUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WenzSpielController extends SpielController {
|
||||
public WenzSpielController(String farbe) {
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
|
||||
List<Karte> farbTrumpfKarten = KartenUtil.getKartenByFarbe(kartenList, farbe);
|
||||
farbTrumpfKarten.removeAll(KartenUtil.getKartenBySymbol(kartenList, "u"));
|
||||
farbTrumpfKarten.addAll(unterKarten);
|
||||
kartenList.removeAll(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(farbTrumpfKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
|
||||
public WenzSpielController() {
|
||||
List<Karte> kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
List<Karte> unterKarten = KartenUtil.getKartenBySymbol(kartenList, "u");
|
||||
|
||||
kartenList.removeAll(unterKarten);
|
||||
|
||||
this.trumpfKarten = new ArrayList<>(unterKarten);
|
||||
this.farbKarten = new ArrayList<>(kartenList);
|
||||
}
|
||||
}
|
||||
183
src/main/java/org/schafkopf/BackendServer.java
Normal file
183
src/main/java/org/schafkopf/BackendServer.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.github.cdimascio.dotenv.Dotenv;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlets.CrossOriginFilter;
|
||||
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
|
||||
|
||||
/** Main Class that represents the Backend Server. */
|
||||
public class BackendServer {
|
||||
private final Server server;
|
||||
private final ServerConnector connector;
|
||||
private final Schafkopf schafkopfGame;
|
||||
private final KartenLeser nfcLeser;
|
||||
private final List<FrontendEndpoint> frontendEndpoints = new ArrayList<>();
|
||||
private CountDownLatch nfcLatch = new CountDownLatch(1);
|
||||
private Boolean readingMode = false;
|
||||
private String uidString = "";
|
||||
|
||||
/** Creates an Instance of the Backend Server. */
|
||||
public BackendServer() {
|
||||
Dotenv dotenv = Dotenv.configure().directory("./").load();
|
||||
server = new Server();
|
||||
InetSocketAddress address = new InetSocketAddress(dotenv.get("VITE_APP_WEBSOCKET_IP"), 8080);
|
||||
connector = new ServerConnector(server);
|
||||
connector.setHost(address.getHostName());
|
||||
connector.setPort(address.getPort());
|
||||
server.addConnector(connector);
|
||||
|
||||
schafkopfGame = new Schafkopf(this);
|
||||
nfcLeser = new KartenLeser(this);
|
||||
|
||||
// Setup the basic application "context" for this application at "/"
|
||||
// This is also known as the handler tree (in jetty speak)
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
server.setHandler(context);
|
||||
|
||||
// Configure CORS settings
|
||||
configureCors(context);
|
||||
|
||||
// Configure specific websocket behavior
|
||||
JettyWebSocketServletContainerInitializer.configure(
|
||||
context,
|
||||
(servletContext, wsContainer) -> {
|
||||
// Configure default max size
|
||||
wsContainer.setMaxTextMessageSize(65535);
|
||||
wsContainer.setIdleTimeout(Duration.ofDays(300000));
|
||||
// Add websockets
|
||||
wsContainer.addMapping("/schafkopf-events/*", new FrontendEndpointCreator(this));
|
||||
});
|
||||
}
|
||||
|
||||
/** The main entrypoint of the Application. */
|
||||
public static void main(String[] args) throws Exception {
|
||||
BackendServer server = new BackendServer();
|
||||
server.setPort(8080);
|
||||
server.start();
|
||||
server.join();
|
||||
}
|
||||
|
||||
private void configureCors(ServletContextHandler context) {
|
||||
// Enable CORS for all paths
|
||||
FilterHolder cors = context.addFilter(CrossOriginFilter.class, "/*", null);
|
||||
|
||||
// Configure allowed origins, headers, and methods
|
||||
cors.setInitParameter("allowedOrigins", "*");
|
||||
cors.setInitParameter("allowedHeaders", "X-Requested-With,Content-Type,Accept,Origin");
|
||||
cors.setInitParameter("allowedMethods", "GET,POST,PUT,DELETE,OPTIONS");
|
||||
|
||||
// Add filter mappings
|
||||
EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST);
|
||||
context.addFilter(cors, "*", types);
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
connector.setPort(port);
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
server.start();
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return server.getURI();
|
||||
}
|
||||
|
||||
public void stop() throws Exception {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException {
|
||||
server.join();
|
||||
}
|
||||
|
||||
public void addFrontendEndpoint(FrontendEndpoint endpoint) {
|
||||
frontendEndpoints.add(endpoint);
|
||||
}
|
||||
|
||||
public void removeFrontendEndpoint(FrontendEndpoint endpoint) {
|
||||
frontendEndpoints.remove(endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends Message to all Frontend Instances.
|
||||
*
|
||||
* @param message Message to send (String).
|
||||
*/
|
||||
public void sendMessageToAllFrontendEndpoints(String message) {
|
||||
for (FrontendEndpoint endpoint : frontendEndpoints) {
|
||||
endpoint.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends Message to all Frontend Instances.
|
||||
*
|
||||
* @param message Message to send (JsonObject).
|
||||
*/
|
||||
public void sendMessageToAllFrontendEndpoints(JsonObject message) {
|
||||
for (FrontendEndpoint endpoint : frontendEndpoints) {
|
||||
endpoint.sendMessage(message.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void startSchafkopfGame() {
|
||||
schafkopfGame.startGame();
|
||||
}
|
||||
|
||||
public void stopSchafkopfGame() {
|
||||
schafkopfGame.stopGame();
|
||||
}
|
||||
|
||||
public void showTrumpf() {
|
||||
schafkopfGame.showTrumpf();
|
||||
}
|
||||
|
||||
public void showFarbe() {
|
||||
schafkopfGame.showFarbe();
|
||||
}
|
||||
|
||||
public void setGame(String message) {
|
||||
schafkopfGame.setGame(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks uid of scanned card and do nothing if Server is not in reading mode.
|
||||
*
|
||||
* @param uidString uid to check.
|
||||
*/
|
||||
public void nfcGelesen(String uidString) {
|
||||
if (this.uidString.equals(uidString)) {
|
||||
return;
|
||||
}
|
||||
if (!this.readingMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.uidString = uidString;
|
||||
nfcLatch.countDown();
|
||||
}
|
||||
|
||||
/** method to call to wait for NFC input. */
|
||||
public String waitForCardScan() throws InterruptedException {
|
||||
this.readingMode = true;
|
||||
nfcLatch.await();
|
||||
Thread.sleep(20);
|
||||
this.readingMode = false;
|
||||
nfcLatch = new CountDownLatch(1);
|
||||
return this.uidString;
|
||||
}
|
||||
}
|
||||
77
src/main/java/org/schafkopf/FrontendEndpoint.java
Normal file
77
src/main/java/org/schafkopf/FrontendEndpoint.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
|
||||
/** Class that represents one Frontend Connection. */
|
||||
public class FrontendEndpoint extends WebSocketAdapter {
|
||||
private final CountDownLatch closureLatch = new CountDownLatch(1);
|
||||
private BackendServer backendServer;
|
||||
|
||||
public FrontendEndpoint(BackendServer backendServer) {
|
||||
this.backendServer = backendServer;
|
||||
System.out.println("new FrontendEndpoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session session) {
|
||||
super.onWebSocketConnect(session);
|
||||
String clientIp = session.getRemoteAddress().toString();
|
||||
System.out.println("Endpoint connected from ip: " + clientIp);
|
||||
|
||||
backendServer.addFrontendEndpoint(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(String message) {
|
||||
super.onWebSocketText(message);
|
||||
System.out.println("Received TEXT message:" + message);
|
||||
|
||||
if (message.contains("startsimulation")) {
|
||||
backendServer.startSchafkopfGame();
|
||||
}
|
||||
|
||||
if (message.contains("stopsimulation")) {
|
||||
backendServer.stopSchafkopfGame();
|
||||
}
|
||||
|
||||
if (message.contains("showtrumpf")) {
|
||||
backendServer.showTrumpf();
|
||||
}
|
||||
|
||||
if (message.contains("showfarben")) {
|
||||
backendServer.showFarbe();
|
||||
}
|
||||
|
||||
if (message.contains("setgame")) {
|
||||
backendServer.setGame(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketClose(int statusCode, String reason) {
|
||||
super.onWebSocketClose(statusCode, reason);
|
||||
|
||||
backendServer.removeFrontendEndpoint(this);
|
||||
|
||||
System.out.println("Socket Closed: [" + statusCode + "] " + reason);
|
||||
closureLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketError(Throwable cause) {
|
||||
super.onWebSocketError(cause);
|
||||
cause.printStackTrace(System.err);
|
||||
}
|
||||
|
||||
/** send a Message to the connected FrontEnd. */
|
||||
public void sendMessage(String message) {
|
||||
try {
|
||||
getRemote().sendString(message);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/main/java/org/schafkopf/FrontendEndpointCreator.java
Normal file
23
src/main/java/org/schafkopf/FrontendEndpointCreator.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
|
||||
|
||||
/**
|
||||
* Creater to make new Instances of the FrontendConnection.
|
||||
*/
|
||||
public class FrontendEndpointCreator implements JettyWebSocketCreator {
|
||||
private BackendServer backendServer;
|
||||
|
||||
public FrontendEndpointCreator(BackendServer backendServer) {
|
||||
this.backendServer = backendServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(
|
||||
JettyServerUpgradeRequest jettyServerUpgradeRequest,
|
||||
JettyServerUpgradeResponse jettyServerUpgradeResponse) {
|
||||
return new FrontendEndpoint(this.backendServer);
|
||||
}
|
||||
}
|
||||
73
src/main/java/org/schafkopf/KartenLeser.java
Normal file
73
src/main/java/org/schafkopf/KartenLeser.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import com.pi4j.io.i2c.I2C;
|
||||
import java.io.IOException;
|
||||
import mk.hsilomedus.pn532.Pn532ContextHelper;
|
||||
import mk.hsilomedus.pn532.Pn532I2c;
|
||||
import mk.hsilomedus.pn532.Pn532SamThread;
|
||||
import mk.hsilomedus.pn532.Pn532SamThread.Pn532SamThreadListener;
|
||||
|
||||
/**
|
||||
* Class that represents the NFC Reader.
|
||||
*/
|
||||
public final class KartenLeser {
|
||||
|
||||
private static BackendServer server;
|
||||
|
||||
/**
|
||||
* Creates an Instance of the KartenLeser.
|
||||
*
|
||||
* @param server Backend Server to call methods on.
|
||||
*/
|
||||
public KartenLeser(BackendServer server) {
|
||||
this.server = server;
|
||||
|
||||
new Thread(
|
||||
() -> {
|
||||
new KartenListener().run();
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
public static final void main(String[] args) throws IOException {}
|
||||
|
||||
private static class KartenListener implements Pn532SamThreadListener {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
Pn532SamThread<I2C> i2cThread = new Pn532SamThread<>(this, new Pn532I2c());
|
||||
|
||||
public void run() {
|
||||
Pn532ContextHelper.initialize();
|
||||
i2cThread.start();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closeThread(i2cThread);
|
||||
Pn532ContextHelper.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveMessage(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uidReceived(String displayName, byte[] uid) {
|
||||
server.nfcGelesen(Pn532SamThreadListener.getUidString(uid));
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void closeThread(Pn532SamThread thread) {
|
||||
if (thread != null && thread.isAlive()) {
|
||||
thread.close();
|
||||
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Error closing thread: " + e.getMessage());
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
194
src/main/java/org/schafkopf/Schafkopf.java
Normal file
194
src/main/java/org/schafkopf/Schafkopf.java
Normal file
@@ -0,0 +1,194 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
import org.schafkopf.player.BotPlayer;
|
||||
import org.schafkopf.player.LocalPlayer;
|
||||
import org.schafkopf.player.Player;
|
||||
import org.schafkopf.spielcontroller.FarbGeierController;
|
||||
import org.schafkopf.spielcontroller.FarbSoloController;
|
||||
import org.schafkopf.spielcontroller.FarbWenzController;
|
||||
import org.schafkopf.spielcontroller.GeierController;
|
||||
import org.schafkopf.spielcontroller.SauSpielController;
|
||||
import org.schafkopf.spielcontroller.SpielController;
|
||||
import org.schafkopf.spielcontroller.WenzController;
|
||||
|
||||
/** The main class representing the Schafkopf game. */
|
||||
public class Schafkopf {
|
||||
private final BackendServer server;
|
||||
|
||||
/** The game controller. This is the class that implements the game logic. */
|
||||
private SpielController spiel = new SauSpielController(0, KartenFarbe.EICHEL);
|
||||
|
||||
private final Player[] player = {
|
||||
new BotPlayer(), new LocalPlayer(this), new LocalPlayer(this), new LocalPlayer(this)
|
||||
};
|
||||
|
||||
private boolean gameState = false;
|
||||
private Thread spielThread;
|
||||
|
||||
public Player[] getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the Schafkopf class.
|
||||
*
|
||||
* @param server The backend server associated with the game.
|
||||
*/
|
||||
Schafkopf(BackendServer server) {
|
||||
this.server = server;
|
||||
System.out.println("SchaffKopfGame erstellt");
|
||||
}
|
||||
|
||||
/** Sends all Trumpf Karten of the current GameType to the Frontend. */
|
||||
public void showTrumpf() {
|
||||
server.sendMessageToAllFrontendEndpoints(spiel.getTrumpfKarten().getJson());
|
||||
}
|
||||
|
||||
/** Sends all Farb Karten of the current GameType to the Frontend. */
|
||||
public void showFarbe() {
|
||||
server.sendMessageToAllFrontendEndpoints(spiel.getFarbKarten().getJson());
|
||||
}
|
||||
|
||||
/** Waits for a Card and returns a Karte Object. */
|
||||
public Karte wartetAufKarte() {
|
||||
String uid = null;
|
||||
System.out.println("Starte Warten auf Karte");
|
||||
try {
|
||||
uid = server.waitForCardScan();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Karte karte = KartenUtil.getIdOfUid(uid);
|
||||
|
||||
if (karte == null) {
|
||||
System.out.println("Ungültige Karte");
|
||||
return wartetAufKarte();
|
||||
}
|
||||
server.sendMessageToAllFrontendEndpoints(karte.getJson());
|
||||
System.out.println("Karte gescannt: " + karte.getName());
|
||||
System.out.println("Beende Warten auf Karte");
|
||||
return karte;
|
||||
}
|
||||
|
||||
/** Set GameState to "started" and start Game Thread. */
|
||||
public void startGame() {
|
||||
if (gameState) {
|
||||
System.out.println("Game already started!");
|
||||
server.sendMessageToAllFrontendEndpoints("Game already started!");
|
||||
} else {
|
||||
gameState = true;
|
||||
System.out.println("Start Game");
|
||||
|
||||
// KartenListe botHand = KartenUtil.zieheZufallsHand(8);
|
||||
KartenListe botHand = new KartenListe();
|
||||
botHand.addKarten(Karte.EICHEL_7);
|
||||
botHand.addKarten(Karte.EICHEL_8);
|
||||
botHand.addKarten(Karte.EICHEL_9);
|
||||
botHand.addKarten(Karte.EICHEL_K);
|
||||
|
||||
botHand.addKarten(Karte.EICHEL_X);
|
||||
botHand.addKarten(Karte.EICHEL_A);
|
||||
botHand.addKarten(Karte.EICHEL_U);
|
||||
botHand.addKarten(Karte.EICHEL_O);
|
||||
for (Player currentPlayer : player) {
|
||||
if (currentPlayer instanceof BotPlayer botPlayer) {
|
||||
// Perform actions specific to BotPlayer
|
||||
botPlayer.setCards(botHand); // Replace with the actual method you want to call
|
||||
}
|
||||
}
|
||||
|
||||
server.sendMessageToAllFrontendEndpoints("Start Game");
|
||||
server.sendMessageToAllFrontendEndpoints(botHand.getJson());
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
spielThread = new Thread(() -> new Spielablauf(this, spiel));
|
||||
|
||||
spielThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/** Set GameState to "stopped" and interrupt Game Thread. */
|
||||
public void stopGame() {
|
||||
if (!gameState) {
|
||||
System.out.println("no active Game!");
|
||||
server.sendMessageToAllFrontendEndpoints("no active Game!");
|
||||
} else {
|
||||
gameState = false;
|
||||
System.out.println("Stop Game");
|
||||
server.sendMessageToAllFrontendEndpoints("Stop Game");
|
||||
}
|
||||
|
||||
spielThread.interrupt();
|
||||
}
|
||||
|
||||
/** Set GameType. */
|
||||
public void setGame(String message) {
|
||||
System.out.println("Set Game: " + message);
|
||||
server.sendMessageToAllFrontendEndpoints("Set Game: " + message);
|
||||
switch (message) {
|
||||
case "setgame:herzsolo":
|
||||
this.spiel = new FarbSoloController(0, KartenFarbe.HERZ);
|
||||
break;
|
||||
case "setgame:blattsolo":
|
||||
this.spiel = new FarbSoloController(0, KartenFarbe.BLATT);
|
||||
break;
|
||||
case "setgame:eichelsolo":
|
||||
this.spiel = new FarbSoloController(0, KartenFarbe.EICHEL);
|
||||
break;
|
||||
case "setgame:schellsolo":
|
||||
this.spiel = new FarbSoloController(0, KartenFarbe.SCHELL);
|
||||
break;
|
||||
|
||||
case "setgame:wenz":
|
||||
this.spiel = new WenzController(0);
|
||||
break;
|
||||
case "setgame:geier":
|
||||
this.spiel = new GeierController(0);
|
||||
break;
|
||||
|
||||
case "setgame:eichelwenz":
|
||||
this.spiel = new FarbWenzController(0, KartenFarbe.EICHEL);
|
||||
break;
|
||||
case "setgame:herzwenz":
|
||||
this.spiel = new FarbWenzController(0, KartenFarbe.HERZ);
|
||||
break;
|
||||
case "setgame:blattwenz":
|
||||
this.spiel = new FarbWenzController(0, KartenFarbe.BLATT);
|
||||
break;
|
||||
case "setgame:schellwenz":
|
||||
this.spiel = new FarbWenzController(0, KartenFarbe.SCHELL);
|
||||
break;
|
||||
|
||||
case "setgame:eichelgeier":
|
||||
this.spiel = new FarbGeierController(0, KartenFarbe.EICHEL);
|
||||
break;
|
||||
case "setgame:herzgeier":
|
||||
this.spiel = new FarbGeierController(0, KartenFarbe.HERZ);
|
||||
break;
|
||||
case "setgame:blattgeier":
|
||||
this.spiel = new FarbGeierController(0, KartenFarbe.BLATT);
|
||||
break;
|
||||
case "setgame:schellgeier":
|
||||
this.spiel = new FarbGeierController(0, KartenFarbe.SCHELL);
|
||||
break;
|
||||
|
||||
case "setgame:sauspiel":
|
||||
this.spiel = new SauSpielController(0, KartenFarbe.EICHEL);
|
||||
break;
|
||||
default:
|
||||
System.out.println("Ungültiges Spiel");
|
||||
}
|
||||
}
|
||||
|
||||
public BackendServer getServer() {
|
||||
return this.server;
|
||||
}
|
||||
}
|
||||
75
src/main/java/org/schafkopf/Spielablauf.java
Normal file
75
src/main/java/org/schafkopf/Spielablauf.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package org.schafkopf;
|
||||
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.player.Player;
|
||||
import org.schafkopf.spielcontroller.SpielController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** The main class that controlls the game flow. */
|
||||
public class Spielablauf {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(Spielablauf.class);
|
||||
private final KartenListe gespielteKarten;
|
||||
|
||||
private final KartenListe tischKarten = new KartenListe();
|
||||
|
||||
private final SpielController spiel;
|
||||
|
||||
private final Player[] players;
|
||||
|
||||
private final Schafkopf schafkopf;
|
||||
|
||||
private int gemachteStiche;
|
||||
|
||||
Spielablauf(Schafkopf schafkopf, SpielController spiel) {
|
||||
this.schafkopf = schafkopf;
|
||||
this.spiel = spiel;
|
||||
this.players = schafkopf.getPlayer();
|
||||
gespielteKarten = new KartenListe();
|
||||
gemachteStiche = 0;
|
||||
try {
|
||||
einStich();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Method to Handle flow of one Game. */
|
||||
public void einStich() throws InterruptedException {
|
||||
logger.info("Starte Stiche");
|
||||
int rauskommer = 0;
|
||||
while (gemachteStiche < 8) {
|
||||
schafkopf.getServer().sendMessageToAllFrontendEndpoints(gespielteKarten.getJson());
|
||||
logger.info("Stich: {}", gemachteStiche);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
schafkopf.getServer().sendMessageToAllFrontendEndpoints(tischKarten.getJson());
|
||||
int nextPlayer = (i + rauskommer) % 4;
|
||||
|
||||
logger.info("Spieler ist dran: {}", nextPlayer);
|
||||
|
||||
tischKarten.addKarten(players[nextPlayer].play(spiel, tischKarten));
|
||||
schafkopf.getServer().sendMessageToAllFrontendEndpoints(tischKarten.getJson());
|
||||
}
|
||||
schafkopf.getServer().sendMessageToAllFrontendEndpoints(tischKarten.getJson());
|
||||
int stichSpieler = SpielController.welcheKarteSticht(tischKarten);
|
||||
|
||||
|
||||
|
||||
Thread.sleep(2000);
|
||||
logger.info("Stiche ende");
|
||||
|
||||
rauskommer = (rauskommer + stichSpieler) % 4;
|
||||
logger.warn("Karte sticht: {}", rauskommer);
|
||||
//rauskommer = 0;
|
||||
|
||||
gespielteKarten.addKarten(tischKarten);
|
||||
|
||||
tischKarten.clear();
|
||||
|
||||
gemachteStiche++;
|
||||
}
|
||||
schafkopf.getServer().sendMessageToAllFrontendEndpoints(gespielteKarten.getJson());
|
||||
schafkopf.stopGame();
|
||||
}
|
||||
}
|
||||
85
src/main/java/org/schafkopf/karte/Karte.java
Normal file
85
src/main/java/org/schafkopf/karte/Karte.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package org.schafkopf.karte;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/** enum to represent all cards in the game. */
|
||||
public enum Karte {
|
||||
EICHEL_7(KartenFarbe.EICHEL, KartenSymbol.SEVEN),
|
||||
EICHEL_8(KartenFarbe.EICHEL, KartenSymbol.EIGHT),
|
||||
EICHEL_9(KartenFarbe.EICHEL, KartenSymbol.NINE),
|
||||
EICHEL_X(KartenFarbe.EICHEL, KartenSymbol.TEN),
|
||||
EICHEL_K(KartenFarbe.EICHEL, KartenSymbol.KOENIG),
|
||||
EICHEL_A(KartenFarbe.EICHEL, KartenSymbol.ASS),
|
||||
EICHEL_U(KartenFarbe.EICHEL, KartenSymbol.UNTER),
|
||||
EICHEL_O(KartenFarbe.EICHEL, KartenSymbol.OBER),
|
||||
BLATT_7(KartenFarbe.BLATT, KartenSymbol.SEVEN),
|
||||
BLATT_8(KartenFarbe.BLATT, KartenSymbol.EIGHT),
|
||||
BLATT_9(KartenFarbe.BLATT, KartenSymbol.NINE),
|
||||
BLATT_X(KartenFarbe.BLATT, KartenSymbol.TEN),
|
||||
BLATT_K(KartenFarbe.BLATT, KartenSymbol.KOENIG),
|
||||
BLATT_A(KartenFarbe.BLATT, KartenSymbol.ASS),
|
||||
BLATT_U(KartenFarbe.BLATT, KartenSymbol.UNTER),
|
||||
BLATT_O(KartenFarbe.BLATT, KartenSymbol.OBER),
|
||||
SCHELL_7(KartenFarbe.SCHELL, KartenSymbol.SEVEN),
|
||||
SCHELL_8(KartenFarbe.SCHELL, KartenSymbol.EIGHT),
|
||||
SCHELL_9(KartenFarbe.SCHELL, KartenSymbol.NINE),
|
||||
SCHELL_X(KartenFarbe.SCHELL, KartenSymbol.TEN),
|
||||
SCHELL_K(KartenFarbe.SCHELL, KartenSymbol.KOENIG),
|
||||
SCHELL_A(KartenFarbe.SCHELL, KartenSymbol.ASS),
|
||||
SCHELL_U(KartenFarbe.SCHELL, KartenSymbol.UNTER),
|
||||
SCHELL_O(KartenFarbe.SCHELL, KartenSymbol.OBER),
|
||||
HERZ_7(KartenFarbe.HERZ, KartenSymbol.SEVEN),
|
||||
HERZ_8(KartenFarbe.HERZ, KartenSymbol.EIGHT),
|
||||
HERZ_9(KartenFarbe.HERZ, KartenSymbol.NINE),
|
||||
HERZ_X(KartenFarbe.HERZ, KartenSymbol.TEN),
|
||||
HERZ_K(KartenFarbe.HERZ, KartenSymbol.KOENIG),
|
||||
HERZ_A(KartenFarbe.HERZ, KartenSymbol.ASS),
|
||||
HERZ_U(KartenFarbe.HERZ, KartenSymbol.UNTER),
|
||||
HERZ_O(KartenFarbe.HERZ, KartenSymbol.OBER);
|
||||
|
||||
private final String id;
|
||||
private final KartenFarbe farbe;
|
||||
private final KartenSymbol symbol;
|
||||
|
||||
private final String displayName;
|
||||
|
||||
private final int punkte;
|
||||
|
||||
Karte(KartenFarbe farbe, KartenSymbol symbol) {
|
||||
this.farbe = farbe;
|
||||
this.symbol = symbol;
|
||||
this.id = this.name().toLowerCase();
|
||||
this.displayName = farbe.getDisplayName() + " " + symbol.getDisplayName();
|
||||
this.punkte = symbol.getValue();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public KartenFarbe getFarbe() {
|
||||
return this.farbe;
|
||||
}
|
||||
|
||||
public KartenSymbol getSymbol() {
|
||||
return this.symbol;
|
||||
}
|
||||
|
||||
public int getPunkte() {
|
||||
return this.punkte;
|
||||
}
|
||||
|
||||
/** get the Card as a Json Object. */
|
||||
public JsonObject getJson() {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.add("card", gson.toJsonTree(this));
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
21
src/main/java/org/schafkopf/karte/KartenFarbe.java
Normal file
21
src/main/java/org/schafkopf/karte/KartenFarbe.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.schafkopf.karte;
|
||||
|
||||
/**
|
||||
* Enum for all possible Card Colors.
|
||||
*/
|
||||
public enum KartenFarbe {
|
||||
EICHEL("Eichel"),
|
||||
BLATT("Blatt"),
|
||||
HERZ("Herz"),
|
||||
SCHELL("Schell");
|
||||
|
||||
private final String displayName;
|
||||
|
||||
KartenFarbe(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
203
src/main/java/org/schafkopf/karte/KartenListe.java
Normal file
203
src/main/java/org/schafkopf/karte/KartenListe.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package org.schafkopf.karte;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public class KartenListe {
|
||||
private List<Karte> kartenListe;
|
||||
|
||||
public KartenListe() {
|
||||
this.kartenListe = new ArrayList<>();
|
||||
}
|
||||
|
||||
public KartenListe(KartenListe liste) {
|
||||
this.kartenListe = new ArrayList<>(liste.getKartenListe());
|
||||
}
|
||||
|
||||
public List<Karte> getKartenListe() {
|
||||
return this.kartenListe;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public void addKarten(Karte karte) {
|
||||
if (!this.containsKarte(karte)) {
|
||||
this.kartenListe.add(karte);
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Karte bereits vorhanden: " + karte.getName());
|
||||
}
|
||||
|
||||
// methoden zum hinzufügen von karten
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public void addKarten(KartenListe karten) {
|
||||
for (Karte karte : karten.getKartenListe()) {
|
||||
this.addKarten(karte);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public KartenListe removeKarten(KartenListe karten) {
|
||||
KartenListe result = new KartenListe();
|
||||
for (Karte karteWeg : karten.getKartenListe()) {
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getId().equals(karteWeg.getId())) {
|
||||
result.addKarten(karte);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.kartenListe.removeAll(result.getKartenListe());
|
||||
return result;
|
||||
}
|
||||
|
||||
// methoden zum entfernen von karten
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public KartenListe removeKarten(KartenFarbe farbe) {
|
||||
KartenListe result = new KartenListe();
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getFarbe().equals(farbe)) {
|
||||
result.addKarten(karte);
|
||||
}
|
||||
}
|
||||
this.kartenListe.removeAll(result.getKartenListe());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public KartenListe removeKarten(KartenSymbol symbol) {
|
||||
KartenListe result = new KartenListe();
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getSymbol().equals(symbol)) {
|
||||
result.addKarten(karte);
|
||||
}
|
||||
}
|
||||
this.kartenListe.removeAll(result.getKartenListe());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public Karte removeKarten(Karte karteToRemove) {
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getId().equals(karteToRemove.getId())) {
|
||||
this.kartenListe.remove(karte);
|
||||
return karte;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public Karte removeKarten(String idToRemove) {
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getId().equals(idToRemove)) {
|
||||
this.kartenListe.remove(karte);
|
||||
return karte;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
private boolean containsKarte(Karte karte) {
|
||||
for (Karte karteInListe : this.kartenListe) {
|
||||
if (karteInListe.getId().equals(karte.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// get Karten
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public KartenListe getKarten(KartenFarbe farbe) {
|
||||
KartenListe result = new KartenListe();
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getFarbe().equals(farbe)) {
|
||||
result.addKarten(karte);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public KartenListe getKarten(KartenSymbol symbol) {
|
||||
KartenListe result = new KartenListe();
|
||||
for (Karte karte : this.kartenListe) {
|
||||
if (karte.getSymbol().equals(symbol)) {
|
||||
result.addKarten(karte);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public JsonObject getJson() {
|
||||
Gson gson = new Gson();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.add("cards", gson.toJsonTree(this.kartenListe));
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.kartenListe.isEmpty();
|
||||
}
|
||||
|
||||
public Karte getLast() {
|
||||
return this.kartenListe.getLast();
|
||||
}
|
||||
|
||||
public Karte getByIndex(int index) {
|
||||
return this.kartenListe.get(index);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.kartenListe.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* A Class that represents a list of Cards.
|
||||
*/
|
||||
public int indexOf(Karte karte) {
|
||||
for (Karte karteInListe : this.kartenListe) {
|
||||
if (karteInListe.getId().equals(karte.getId())) {
|
||||
return this.kartenListe.indexOf(karteInListe);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.kartenListe.clear();
|
||||
}
|
||||
}
|
||||
38
src/main/java/org/schafkopf/karte/KartenSymbol.java
Normal file
38
src/main/java/org/schafkopf/karte/KartenSymbol.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package org.schafkopf.karte;
|
||||
|
||||
/**
|
||||
* Enum for all possible Card Symbols.
|
||||
*/
|
||||
public enum KartenSymbol {
|
||||
SIX("6", "6", 0),
|
||||
SEVEN("7", "7", 0),
|
||||
EIGHT("8", "8", 0),
|
||||
NINE("9", "9", 0),
|
||||
UNTER("u", "Unter", 2),
|
||||
OBER("o", "Ober", 3),
|
||||
KOENIG("k", "König", 4),
|
||||
TEN("x", "10", 10),
|
||||
ASS("a", "Ass", 11);
|
||||
|
||||
private final String displayName;
|
||||
private final String id;
|
||||
private final int value;
|
||||
|
||||
KartenSymbol(String id, String displayName, int value) {
|
||||
this.displayName = displayName;
|
||||
this.value = value;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
82
src/main/java/org/schafkopf/karte/KartenUtil.java
Normal file
82
src/main/java/org/schafkopf/karte/KartenUtil.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package org.schafkopf.karte;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/** Class that brings usefully functions for Card/s. */
|
||||
public class KartenUtil {
|
||||
|
||||
/** initialize a normal Card Deck. It will be in the standard order. */
|
||||
public static KartenListe initializeSchafKopfCardDeck() {
|
||||
KartenListe deck = new KartenListe();
|
||||
|
||||
for (Karte karte : Karte.values()) {
|
||||
deck.addKarten(karte);
|
||||
}
|
||||
|
||||
deck.removeKarten(KartenSymbol.SIX);
|
||||
return deck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a List of Random Cards.
|
||||
*
|
||||
* @param anzahl count of random cards.
|
||||
*/
|
||||
public static KartenListe zieheZufallsHand(int anzahl) {
|
||||
KartenListe karten = initializeSchafKopfCardDeck();
|
||||
KartenListe gezogeneKarten = new KartenListe();
|
||||
Random random = new Random();
|
||||
|
||||
// Ziehe zufällige Karten
|
||||
for (int i = 0; i < anzahl; i++) {
|
||||
int zufallsIndex = random.nextInt(karten.size());
|
||||
Karte gezogeneKarte = karten.getByIndex(zufallsIndex);
|
||||
gezogeneKarten.addKarten(gezogeneKarte);
|
||||
karten.removeKarten(gezogeneKarte);
|
||||
}
|
||||
return gezogeneKarten;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts Uid from a NFC Card to a card ID.
|
||||
*
|
||||
* @param uid uId to get the Card ID from.
|
||||
*/
|
||||
public static Karte getIdOfUid(String uid) {
|
||||
return switch (uid) {
|
||||
case "04A56BB4780000" -> Karte.EICHEL_7;
|
||||
case "04A46BB4780000" -> Karte.EICHEL_8;
|
||||
case "04A26BB4780000" -> Karte.EICHEL_9;
|
||||
case "04A16BB4780000" -> Karte.EICHEL_X;
|
||||
case "049E6BB4780000" -> Karte.EICHEL_K;
|
||||
case "04A86BB4780000" -> Karte.EICHEL_A;
|
||||
case "04A06BB4780000" -> Karte.EICHEL_U;
|
||||
case "049F6BB4780000" -> Karte.EICHEL_O;
|
||||
case "04F26BB4780000" -> Karte.BLATT_7;
|
||||
case "04A76BB4780000" -> Karte.BLATT_8;
|
||||
case "049B6BB4780000" -> Karte.BLATT_9;
|
||||
case "04996BB4780000" -> Karte.BLATT_X;
|
||||
case "041CD2C2126F81" -> Karte.BLATT_K;
|
||||
case "04A96BB4780000" -> Karte.BLATT_A;
|
||||
case "049A6BB4780000" -> Karte.BLATT_U;
|
||||
case "049D6BB4780000" -> Karte.BLATT_O;
|
||||
case "04936BB4780000" -> Karte.SCHELL_7;
|
||||
case "04F697C2126F80" -> Karte.SCHELL_8;
|
||||
case "04946BB4780000" -> Karte.SCHELL_9;
|
||||
case "04956BB4780000" -> Karte.SCHELL_X;
|
||||
case "04986BB4780000" -> Karte.SCHELL_K;
|
||||
case "04AA6BB4780000" -> Karte.SCHELL_A;
|
||||
case "04966BB4780000" -> Karte.SCHELL_U;
|
||||
case "04976BB4780000" -> Karte.SCHELL_O;
|
||||
case "04F36BB4780000" -> Karte.HERZ_7;
|
||||
case "04B06BB4780000" -> Karte.HERZ_8;
|
||||
case "04AF6BB4780000" -> Karte.HERZ_9;
|
||||
case "04AE6BB4780000" -> Karte.HERZ_X;
|
||||
case "04AB6BB4780000" -> Karte.HERZ_K;
|
||||
case "049C6BB4780000" -> Karte.HERZ_A;
|
||||
case "04AD6BB4780000" -> Karte.HERZ_U;
|
||||
case "04AC6BB4780000" -> Karte.HERZ_O;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
47
src/main/java/org/schafkopf/player/BotPlayer.java
Normal file
47
src/main/java/org/schafkopf/player/BotPlayer.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package org.schafkopf.player;
|
||||
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
import org.schafkopf.spielcontroller.SauSpielController;
|
||||
import org.schafkopf.spielcontroller.SpielController;
|
||||
|
||||
/**
|
||||
* Player that represents the Bot.
|
||||
*/
|
||||
public class BotPlayer extends Player {
|
||||
|
||||
private KartenListe eigeneKarten;
|
||||
private KartenListe unbekannteKarten = KartenUtil.initializeSchafKopfCardDeck();
|
||||
|
||||
public BotPlayer() {
|
||||
// TODO document why this constructor is empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public Karte play(SpielController spiel, KartenListe tischKarten) {
|
||||
|
||||
Karte cardIndex = eigeneKarten.getByIndex(spiel.welcheKarteSpielIch(0,
|
||||
eigeneKarten,
|
||||
eigeneKarten,
|
||||
tischKarten));
|
||||
|
||||
eigeneKarten.removeKarten(cardIndex);
|
||||
|
||||
System.out.println("Eigene Karte legen");
|
||||
return cardIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Cards of the Player.
|
||||
*/
|
||||
public void setCards(KartenListe cards) {
|
||||
System.out.println("Eigene Karte setzen");
|
||||
this.eigeneKarten = cards;
|
||||
this.unbekannteKarten = KartenUtil.initializeSchafKopfCardDeck();
|
||||
this.unbekannteKarten.removeKarten(eigeneKarten);
|
||||
System.out.println("Eigene Karte fertig");
|
||||
}
|
||||
}
|
||||
25
src/main/java/org/schafkopf/player/LocalPlayer.java
Normal file
25
src/main/java/org/schafkopf/player/LocalPlayer.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package org.schafkopf.player;
|
||||
|
||||
import org.schafkopf.Schafkopf;
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.spielcontroller.SpielController;
|
||||
|
||||
/**
|
||||
* Player that plays in real life.
|
||||
*/
|
||||
public class LocalPlayer extends Player {
|
||||
|
||||
private final Schafkopf schafkopf;
|
||||
|
||||
public LocalPlayer(Schafkopf schafkopf) {
|
||||
this.schafkopf = schafkopf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Karte play(SpielController spiel, KartenListe tischKarten) {
|
||||
return schafkopf.wartetAufKarte();
|
||||
}
|
||||
}
|
||||
12
src/main/java/org/schafkopf/player/Player.java
Normal file
12
src/main/java/org/schafkopf/player/Player.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.schafkopf.player;
|
||||
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.spielcontroller.SpielController;
|
||||
|
||||
/**
|
||||
* Class that represents one Player of the game.
|
||||
*/
|
||||
public abstract class Player {
|
||||
public abstract Karte play(SpielController spiel, KartenListe tischKarten);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Farb Geier.
|
||||
*/
|
||||
public class FarbGeierController extends SoloController {
|
||||
/**
|
||||
* Create instance of SpielController.
|
||||
*
|
||||
* @param farbe Trumpffarbe of the Farb Geier.
|
||||
*/
|
||||
public FarbGeierController(int activePlayer, KartenFarbe farbe) {
|
||||
super(activePlayer);
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe oberKarten = kartenList.getKarten(KartenSymbol.OBER);
|
||||
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
|
||||
farbTrumpfKarten.removeKarten(KartenSymbol.OBER);
|
||||
farbTrumpfKarten.addKarten(oberKarten);
|
||||
kartenList.removeKarten(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
|
||||
public int welcheKarteSpielIch(int meinePosition,
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Farb Solo.
|
||||
*/
|
||||
public class FarbSoloController extends SoloController {
|
||||
/**
|
||||
* Create instance of SpielController.
|
||||
*
|
||||
* @param farbe Trumpffarbe of the Farb Solo.
|
||||
*/
|
||||
public FarbSoloController(int activePlayer, KartenFarbe farbe) {
|
||||
super(activePlayer);
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
|
||||
|
||||
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
|
||||
farbTrumpfKarten.removeKarten(KartenSymbol.UNTER);
|
||||
farbTrumpfKarten.removeKarten(KartenSymbol.OBER);
|
||||
farbTrumpfKarten.addKarten(kartenList.getKarten(KartenSymbol.UNTER));
|
||||
farbTrumpfKarten.addKarten(kartenList.getKarten(KartenSymbol.OBER));
|
||||
|
||||
kartenList.removeKarten(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
|
||||
public int welcheKarteSpielIch(int meinePosition,
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Farb Wenz.
|
||||
*/
|
||||
public class FarbWenzController extends SoloController {
|
||||
/**
|
||||
* Create instance of SpielController.
|
||||
*
|
||||
* @param farbe Trumpffarbe of the Farb Wenz.
|
||||
*/
|
||||
public FarbWenzController(int activePlayer, KartenFarbe farbe) {
|
||||
super(activePlayer);
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
|
||||
KartenListe farbTrumpfKarten = kartenList.getKarten(farbe);
|
||||
farbTrumpfKarten.removeKarten(KartenSymbol.UNTER);
|
||||
farbTrumpfKarten.addKarten(unterKarten);
|
||||
kartenList.removeKarten(farbTrumpfKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(farbTrumpfKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
|
||||
public int welcheKarteSpielIch(int meinePosition,
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Geier Game.
|
||||
*/
|
||||
public class GeierController extends GeierWenzController {
|
||||
/**
|
||||
* Create instance of Geier Game.
|
||||
*/
|
||||
public GeierController(int activePlayer) {
|
||||
super(activePlayer);
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe oberKarten = kartenList.getKarten(KartenSymbol.OBER);
|
||||
|
||||
kartenList.removeKarten(oberKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(oberKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import java.util.List;
|
||||
import org.schafkopf.karte.Karte;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Geier/Wenz Game.
|
||||
*/
|
||||
public class GeierWenzController extends SoloController {
|
||||
|
||||
public GeierWenzController(int activePlayer) {
|
||||
super(activePlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int welcheKarteSpielIch(int meinePosition, KartenListe gespielteKarten,
|
||||
KartenListe meineHand, KartenListe tischKarten) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Sau Spiel Game.
|
||||
*/
|
||||
public class SauSpielController extends StandardController {
|
||||
|
||||
KartenFarbe suchFarbe;
|
||||
boolean istSpieler;
|
||||
|
||||
/**
|
||||
* Class that represents one Card of the game.
|
||||
*/
|
||||
public SauSpielController(int activePlayer, KartenFarbe farbe) {
|
||||
super(activePlayer);
|
||||
this.suchFarbe = suchFarbe;
|
||||
this.istSpieler = istSpieler;
|
||||
}
|
||||
|
||||
/**
|
||||
* choose witch Card should be played with the right Game logic.
|
||||
*/
|
||||
public int welcheKarteSpielIch(int meinePosition,
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
|
||||
System.out.println("Ich spiele eine Karte Sauspiel");
|
||||
|
||||
int spielerNummer = tischKarten.size();
|
||||
|
||||
if (istSpieler && tischKarten.getLast().getFarbe().equals(suchFarbe)) {
|
||||
return farbeZugeben(meineHand, suchFarbe, 2);
|
||||
}
|
||||
|
||||
switch (spielerNummer) {
|
||||
case 0:
|
||||
if (istSpieler) {
|
||||
return meineHand.size() - 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 1:
|
||||
if (istSpieler) {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 2);
|
||||
} else {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 0);
|
||||
}
|
||||
case 2:
|
||||
if (istSpieler) {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 2);
|
||||
} else {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 0);
|
||||
}
|
||||
case 3:
|
||||
if (istSpieler) {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 2);
|
||||
} else {
|
||||
return farbeZugeben(meineHand, tischKarten.getLast().getFarbe(), 0);
|
||||
}
|
||||
default:
|
||||
System.out.println("Ungültige SpielerNummer");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
|
||||
/**
|
||||
* abstract Class that represents Logic of a Solo like Game.
|
||||
*/
|
||||
public abstract class SoloController extends SpielController {
|
||||
|
||||
SoloController(int activePlayer) {
|
||||
super(activePlayer);
|
||||
}
|
||||
|
||||
public int welcheKarteSpielIch(
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
116
src/main/java/org/schafkopf/spielcontroller/SpielController.java
Normal file
116
src/main/java/org/schafkopf/spielcontroller/SpielController.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/** Base Class of Game Controllers. */
|
||||
public abstract class SpielController {
|
||||
protected static KartenListe trumpfKarten;
|
||||
protected static KartenListe farbKarten;
|
||||
|
||||
protected static int activePlayer;
|
||||
|
||||
public SpielController(int activePlayer) {
|
||||
this.activePlayer = activePlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create instance of SpielController.
|
||||
*
|
||||
* @param meineHand Cards one Player holds.
|
||||
* @param farbe color the Player has to play.
|
||||
* @param mode Mode the player chooses a Card if multiple are available.
|
||||
*/
|
||||
public static int farbeZugeben(KartenListe meineHand, KartenFarbe farbe, int mode) {
|
||||
KartenListe farbKarten = meineHand.getKarten(farbe);
|
||||
farbKarten.removeKarten(trumpfKarten);
|
||||
if (farbKarten.size() == 1) {
|
||||
return meineHand.indexOf(farbKarten.getByIndex(0));
|
||||
}
|
||||
if (farbKarten.size() > 1) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return meineHand.indexOf(farbKarten.getLast());
|
||||
case 2:
|
||||
return meineHand.indexOf(farbKarten.getLast());
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (farbKarten.isEmpty()) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return 0;
|
||||
case 2:
|
||||
return meineHand.size() - 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts Cards, so they are in the right order for the active game.
|
||||
*
|
||||
* @param karten Trumpffarbe of the Farb Geier.
|
||||
*/
|
||||
public static void sortiereKarten(KartenListe karten) {
|
||||
KartenListe kartenReihenfolge = new KartenListe(farbKarten);
|
||||
kartenReihenfolge.addKarten(trumpfKarten);
|
||||
|
||||
KartenListe kartenListe = KartenUtil.initializeSchafKopfCardDeck();
|
||||
|
||||
kartenListe.removeKarten(karten);
|
||||
kartenReihenfolge.removeKarten(kartenListe);
|
||||
|
||||
karten.clear();
|
||||
karten.addKarten(kartenReihenfolge);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks, which card has the highest strength and will win one Stich.
|
||||
*
|
||||
* @param karten Cards to check.
|
||||
*/
|
||||
public static int welcheKarteSticht(KartenListe karten) {
|
||||
KartenListe kartenNew = new KartenListe(karten);
|
||||
sortiereKarten(kartenNew);
|
||||
KartenListe farbTischKarten = kartenNew.removeKarten(trumpfKarten);
|
||||
System.out.println("trumpfKarten:");
|
||||
System.out.println(trumpfKarten.getJson());
|
||||
|
||||
if (!farbTischKarten.isEmpty()) {
|
||||
System.out.println("trumpfkarten:");
|
||||
System.out.println(farbTischKarten.getJson());
|
||||
return karten.indexOf(farbTischKarten.getLast());
|
||||
} else {
|
||||
KartenFarbe firstColor = karten.getByIndex(0).getFarbe();
|
||||
KartenListe firstColorCards = kartenNew.removeKarten(firstColor);
|
||||
|
||||
System.out.println("firstcolor:");
|
||||
System.out.println(firstColorCards.getJson());
|
||||
|
||||
return karten.indexOf(firstColorCards.getLast());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int welcheKarteSpielIch(
|
||||
int meinePosition,
|
||||
KartenListe gespielteKarten,
|
||||
KartenListe meineHand,
|
||||
KartenListe tischKarten);
|
||||
|
||||
public KartenListe getTrumpfKarten() {
|
||||
return trumpfKarten;
|
||||
}
|
||||
|
||||
public KartenListe getFarbKarten() {
|
||||
return farbKarten;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenFarbe;
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that has the standard Card Deck for Sauspiel, Bettel und Co.
|
||||
*/
|
||||
public abstract class StandardController extends SpielController {
|
||||
|
||||
StandardController(int activePlayer) {
|
||||
super(activePlayer);
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe herzKarten = kartenList.getKarten(KartenFarbe.HERZ);
|
||||
herzKarten.removeKarten(KartenSymbol.UNTER);
|
||||
herzKarten.removeKarten(KartenSymbol.OBER);
|
||||
|
||||
herzKarten.addKarten(kartenList.getKarten(KartenSymbol.UNTER));
|
||||
herzKarten.addKarten(kartenList.getKarten(KartenSymbol.OBER));
|
||||
|
||||
kartenList.removeKarten(herzKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(herzKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
|
||||
public abstract int welcheKarteSpielIch(int meinePosition,
|
||||
KartenListe gespielteKarten, KartenListe meineHand, KartenListe tischKarten);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.schafkopf.spielcontroller;
|
||||
|
||||
import org.schafkopf.karte.KartenListe;
|
||||
import org.schafkopf.karte.KartenSymbol;
|
||||
import org.schafkopf.karte.KartenUtil;
|
||||
|
||||
/**
|
||||
* SpielController that implements Logic of a Wenz Game.
|
||||
*/
|
||||
public class WenzController extends GeierWenzController {
|
||||
/**
|
||||
* Create instance of Wenz Game.
|
||||
*/
|
||||
public WenzController(int activePlayer) {
|
||||
super(activePlayer);
|
||||
this.activePlayer = activePlayer;
|
||||
KartenListe kartenList = KartenUtil.initializeSchafKopfCardDeck();
|
||||
KartenListe unterKarten = kartenList.getKarten(KartenSymbol.UNTER);
|
||||
|
||||
kartenList.removeKarten(unterKarten);
|
||||
|
||||
this.trumpfKarten = new KartenListe(unterKarten);
|
||||
this.farbKarten = new KartenListe(kartenList);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user