merge widgets with development

This commit is contained in:
ramollia
2025-11-27 15:57:46 +01:00
parent cbe01fbca5
commit 38681c5db0
30 changed files with 1122 additions and 2942 deletions

View File

@@ -1,9 +1,591 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<inspection_tool class="AccessStaticViaInstance" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Anonymous2MethodRef" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AnonymousHasLambdaAlternative" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AnonymousInnerClass" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ArrayCanBeReplacedWithEnumValues" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ArrayCreationWithoutNewKeyword" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ArrayEquals" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ArrayHashCode" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ArrayObjectsEquals" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ArraysAsListWithZeroOrOneArgument" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AssertWithSideEffects" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AssertionCanBeIf" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="AssignmentToCatchBlockParameter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AssignmentUsedAsCondition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AtomicFieldUpdaterIssues" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AtomicFieldUpdaterNotStaticFinal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AutoCloseableResource" enabled="false" level="WARNING" enabled_by_default="false">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,java.lang.foreign.Arena,ofAuto,java.lang.foreign.Arena,global,org.toop.framework.audio.AudioPlayer,play,java.util.Map,remove,java.util.concurrent.Executors,newSingleThreadScheduledExecutor" />
</inspection_tool>
<inspection_tool class="BigDecimalLegacyMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BigDecimalMethodWithoutRoundingCalled" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BooleanConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BooleanExpressionMayBeConditional" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BoxingBoxedValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BusyWait" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CStyleArrayDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CachedNumberConstructorCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CanBeFinal" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_CLASSES" value="false" />
<option name="REPORT_METHODS" value="false" />
<option name="REPORT_FIELDS" value="true" />
</inspection_tool>
<inspection_tool class="CapturingCleaner" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CastCanBeRemovedNarrowingVariableType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CastCanBeReplacedWithVariable" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="CatchMayIgnoreException" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CaughtExceptionImmediatelyRethrown" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CharsetObjectCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ClassCanBeRecord" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ClassEscapesItsScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ClassGetClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ClassMayBeInterface" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="CloneDeclaresCloneNotSupported" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CloneableImplementsClone" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreCloneableDueToInheritance" value="true" />
</inspection_tool>
<inspection_tool class="CodeBlock2Expr" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CollectionAddAllCanBeReplacedWithConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CollectionAddedToSelf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CommentedOutCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ComparatorCombinators" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ComparatorMethodParameterNotUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ComparatorResultComparison" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ComparisonOfShortAndChar" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ComparisonToNaN" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConditionCoveredByFurtherCondition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConditionalBreakInInfiniteLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConditionalCanBeOptional" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ConditionalCanBePushedInsideExpression" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ConditionalExpression" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ConditionalExpressionWithIdenticalBranches" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConfusingElse" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="reportWhenNoStatementFollow" value="true" />
</inspection_tool>
<inspection_tool class="ConfusingMainMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstantConditionalExpression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstantExpression" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ConstantValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ContinueOrBreakFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Contract" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ControlFlowStatementWithoutBraces" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="Convert2Diamond" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Convert2Lambda" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Convert2MethodRef" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Convert2streamapi" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ConvertToBasicLatin" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="CopyConstructorMissesField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DanglingJavadoc" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DataFlowIssue" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
</inspection_tool>
<inspection_tool class="DataProviderReturnType" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="DeconstructionCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DefaultAnnotationParam" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DefaultNotLastCaseInSwitch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DeprecatedIsStillUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Deprecation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DialogTitleCapitalization" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DiamondCanBeReplacedWithExplicitTypeArguments" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="DivideByZero" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DoubleBraceInitialization" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="DoubleCheckedLocking" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreOnVolatileVariables" value="false" />
</inspection_tool>
<inspection_tool class="DoubleNegation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateBranchesInSwitch" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateCondition" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreSideEffectConditions" value="true" />
</inspection_tool>
<inspection_tool class="DuplicateExpressions" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateThrows" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicatedDataProviderNames" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="EmptyFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyInitializer" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyStatementBody" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportEmptyBlocks" value="true" />
</inspection_tool>
<inspection_tool class="EmptySynchronizedStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyTryBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EndlessStream" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="EnhancedSwitchMigration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EnumSwitchStatementWhichMissesCases" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreSwitchStatementsWithDefault" value="true" />
</inspection_tool>
<inspection_tool class="EqualsBetweenInconvertibleTypes" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EqualsOnSuspiciousObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EqualsReplaceableByObjectsCall" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="EqualsWhichDoesntCheckParameterClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EqualsWithItself" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EscapedSpace" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExcessiveLambdaUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExcessiveRangeCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExplicitArgumentCanBeLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ExplicitArrayFilling" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExplicitToImplicitClassMigration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExpressionComparedToItself" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExpressionMayBeFactorized" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ExtendsAnnotation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExtendsObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExternalizableWithoutPublicNoArgConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ExtractMethodRecommender" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FieldCanBeLocal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FieldMayBeFinal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FillPermitsList" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="FinalMethodInFinalClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinalPrivateMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinalStaticMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinalizeNotProtected" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinallyBlockCannotCompleteNormally" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FoldExpressionIntoStream" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ForCanBeForeach" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_INDEXED_LOOP" value="true" />
<option name="ignoreUntypedCollections" value="false" />
</inspection_tool>
<inspection_tool class="ForLoopReplaceableByWhile" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreLoopsWithoutConditions" value="true" />
</inspection_tool>
<inspection_tool class="ForwardCompatibility" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FrequentlyUsedInheritorInspection" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="FunctionalExpressionCanBeFolded" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FuseStreamOperations" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IOStreamConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IdempotentLoopBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IfCanBeAssertion" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="IfCanBeSwitch" enabled="false" level="WARNING" enabled_by_default="false">
<option name="minimumBranches" value="3" />
<option name="suggestIntSwitches" value="false" />
<option name="suggestEnumSwitches" value="false" />
</inspection_tool>
<inspection_tool class="IfStatementMissingBreakInLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IfStatementWithIdenticalBranches" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportAllNonLibraryCalls" value="false" />
<option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
</inspection_tool>
<inspection_tool class="ImplicitArrayToString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ImplicitSubclassInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="ImplicitToExplicitClassBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="IncompatibleMask" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InconsistentTextBlockIndent" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IncorrectDateTimeFormat" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IncorrectMessageFormat" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IndexOfReplaceableByContains" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InfiniteLoopStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InfiniteRecursion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InnerClassMayBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InsertLiteralUnderscores" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="InstantiatingObjectToGetClassObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InstantiationOfUtilityClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IntegerDivisionInFloatingPointContext" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IntegerMultiplicationImplicitCastToLong" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreNonOverflowingCompileTimeConstants" value="true" />
</inspection_tool>
<inspection_tool class="InterfaceMethodClashesWithObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InvalidComparatorMethodReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IterableUsedAsVararg" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="IteratorHasNextCallsIteratorNext" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java8CollectionRemoveIf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java8ListReplaceAll" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java8ListSort" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java8MapApi" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java8MapForEach" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java9CollectionFactory" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="Java9ModuleExportsPackageToItself" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java9RedundantRequiresStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java9ReflectionClassVisibility" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Java9UndeclaredServiceUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaEmptyModuleInfoFile" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaLangInvokeHandleSignature" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaModuleDefinition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaModuleNaming" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaReflectionInvocation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaReflectionMemberAccess" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaRequiresAutoModule" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavacQuirks" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavadocBlankLines" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavadocDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavadocLinkAsPlainText" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavadocReference" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JoinDeclarationAndAssignmentJava" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LambdaBodyCanBeCodeBlock" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LambdaCanBeMethodCall" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LambdaCanBeReplacedWithAnonymous" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LambdaParameterTypeCanBeSpecified" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LengthOneStringsInConcatenation" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LimitedScopeInnerClass" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ListIndexOfReplaceableByContains" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ListRemoveInLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WEAK WARNING" enabled_by_default="false">
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
<inspection_tool class="LongLiteralsEndingWithLowercaseL" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoopConditionNotUpdatedInsideLoop" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreIterators" value="false" />
</inspection_tool>
<inspection_tool class="LoopStatementsThatDontLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LossyConversionCompoundAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MISSORTED_IMPORTS" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MagicConstant" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MalformedDataProvider" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MalformedFormatString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ManualArrayCopy" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ManualArrayToCollectionCopy" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ManualMinMaxCalculation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MappingBeforeCount" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MarkdownDocumentationCommentsMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MarkedForRemoval" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="MaskedAssertion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MathRandomCastToInt" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MathRoundingWithIntArgument" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MeaninglessRecordAnnotationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MetaAnnotationWithoutRuntimeRetention" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MethodCanBeVariableArityMethod" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MethodNameSameAsClassName" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MethodRefCanBeReplacedWithLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MigrateFromJavaLangIo" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MigrateToJavaLangIo" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MismatchedArrayReadWrite" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MismatchedCollectionQueryUpdate" enabled="false" level="WARNING" enabled_by_default="false">
<option name="queryNames">
<value />
</option>
<option name="updateNames">
<value />
</option>
<option name="ignoredClasses">
<value />
</option>
</inspection_tool>
<inspection_tool class="MismatchedJavadocCode" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MismatchedStringBuilderQueryUpdate" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MismatchedStringCase" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MisorderedAssertEqualsArguments" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MissingOverrideAnnotation" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreObjectMethods" value="true" />
<option name="ignoreAnonymousClassMethods" value="false" />
</inspection_tool>
<inspection_tool class="MissingSerialAnnotation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MissortedModifiers" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="m_requireAnnotationsFirst" value="true" />
</inspection_tool>
<inspection_tool class="MoveFieldAssignmentToInitializer" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MultiCatchCanBeSplit" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="MultipleVariablesInDeclaration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="NegativeIntConstantInLongContext" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NewClassNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NewObjectEquality" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NewStringBufferWithCharArgument" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NoExplicitFinalizeCalls" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NonAtomicOperationOnVolatileField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NonFinalFieldInEnum" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NonSerializableWithSerialVersionUIDField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NonStrictComparisonCanBeEquality" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="NotNullFieldNotInitialized" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NullArgumentToVariableArgMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NullableProblems" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
<inspection_tool class="NumberEquality" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NumericOverflow" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ObjectEquality" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="m_ignoreEnums" value="true" />
<option name="m_ignoreClassObjects" value="true" />
<option name="m_ignorePrivateConstructors" value="false" />
</inspection_tool>
<inspection_tool class="ObjectEqualsCanBeEquality" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ObjectsEqualsCanBeSimplified" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ObviousNullCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OctalLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OnlyOneElementUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OptionalAssignedToNull" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OptionalGetWithoutIsPresent" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OptionalIsPresent" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OptionalOfNullableMisuse" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OptionalToIf" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="OptionalUsedAsFieldOrParameterType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OverflowingLoopIndex" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OverwrittenKey" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PackageInfoWithoutPackage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ParameterCanBeLocal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PatternVariableCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PatternVariableHidesField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PatternVariablesCanBeReplacedWithCast" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="PointlessArithmeticExpression" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreExpressionsContainingConstants" value="true" />
</inspection_tool>
<inspection_tool class="PointlessBitwiseExpression" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreExpressionsContainingConstants" value="true" />
</inspection_tool>
<inspection_tool class="PointlessBooleanExpression" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreExpressionsContainingConstants" value="true" />
</inspection_tool>
<inspection_tool class="PointlessNullCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PreviewFeature" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PrimitiveArrayArgumentToVariableArgMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ProtectedMemberInFinalClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PublicField" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreEnums" value="false" />
<option name="ignorableAnnotations">
<value />
</option>
</inspection_tool>
<inspection_tool class="RawUseOfParameterizedType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReadWriteStringCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReassignedVariable" enabled="false" level="TEXT ATTRIBUTES" enabled_by_default="false" />
<inspection_tool class="RecordCanBeClass" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="RedundantArrayCreation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantClassCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantCollectionOperation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantComparatorComparing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantCompareCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantEmbeddedExpression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantEscapeInRegexReplacement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantExplicitClose" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantExplicitVariableType" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="RedundantFileCreation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantJavaTimeOperations" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantLabeledSwitchRuleCodeBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantLambdaParameterType" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="RedundantLengthCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantMethodOverride" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantOperationOnEmptyContainer" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantRecordConstructor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantScheduledForRemovalAnnotation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantStreamOptionalCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantStringFormatCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantThrows" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantTypeArguments" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantUnmodifiable" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReflectionForUnavailableAnnotation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RefusedBequest" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreEmptySuperMethods" value="false" />
<option name="onlyReportWhenAnnotated" value="true" />
</inspection_tool>
<inspection_tool class="RemoveLiteralUnderscores" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ReplaceAllDot" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReplaceAssignmentWithOperatorAssignment" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreLazyOperators" value="true" />
<option name="ignoreObscureOperators" value="false" />
</inspection_tool>
<inspection_tool class="ReplaceInefficientStreamCount" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReplaceNullCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReplaceOnLiteralHasNoEffect" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReplaceWithJavadoc" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ReturnFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReturnSeparatedFromComputation" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ReuseOfLocalVariable" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SafeVarargsDetector" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SafeVarargsHasNoEffect" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SafeVarargsOnNonReifiableType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ScheduledThreadPoolExecutorWithZeroCoreThreads" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SequencedCollectionMethodCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SerialAnnotationUsedOnWrongMember" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SerialVersionUIDNotStaticFinal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SerializableRecordContainsIgnoredMembers" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ShiftOutOfRange" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SillyAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifiableAssertion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifiableBooleanExpression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifiableConditionalExpression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifiableIfStatement" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SimplifyCollector" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifyForEach" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SimplifyOptionalCallChains" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SimplifyStreamApiCallChains" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SingleElementAnnotation" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SingleStatementInBlock" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SlowAbstractSetRemoveAll" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SlowListContainsAll" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SortedCollectionWithNonComparableKeys" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StaticImportCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StaticInitializerReferencesSubClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StreamToLoop" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="StringBufferReplaceableByString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringBufferReplaceableByStringBuilder" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringConcatenationArgumentToLogCall" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="StringConcatenationInLoops" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringConcatenationInsideStringBufferAppend" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringEquality" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringEqualsCharSequence" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringEqualsEmptyString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringOperationCanBeSimplified" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringRepeatCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringTemplateMigration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringTemplateReverseMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="StringTokenizerDelimiter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousArrayMethodCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousDateFormat" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousIndentAfterControlStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousIntegerDivAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousInvocationHandlerImplementation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousListRemoveInLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousMethodCalls" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_CONVERTIBLE_METHOD_CALLS" value="true" />
</inspection_tool>
<inspection_tool class="SuspiciousNameCombination" enabled="false" level="WARNING" enabled_by_default="false">
<group names="x,width,left,right" />
<group names="y,height,top,bottom" />
<ignored>
<option name="METHOD_MATCHER_CONFIG" value="java.io.PrintStream,println,java.io.PrintWriter,println,java.lang.System,identityHashCode,java.sql.PreparedStatement,set.*,java.sql.ResultSet,update.*,java.sql.SQLOutput,write.*,java.lang.Integer,compare.*|toUnsignedLong,java.lang.Long,compare.*,java.lang.Short,compare|toUnsigned.*,java.lang.Byte,compare|toUnsigned.*,java.lang.Character,compare,java.lang.Boolean,compare,java.lang.Math,.*,java.lang.StrictMath,.*" />
</ignored>
</inspection_tool>
<inspection_tool class="SuspiciousReturnByteInputStream" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousSystemArraycopy" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousTernaryOperatorInVarargsCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousToArrayCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SwitchExpressionCanBePushedDown" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SwitchLabeledRuleCanBeCodeBlock" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SwitchStatementWithConfusingDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SwitchStatementWithTooFewBranches" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="2" />
</inspection_tool>
<inspection_tool class="SwitchStatementsWithoutDefault" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="m_ignoreFullyCoveredEnums" value="true" />
</inspection_tool>
<inspection_tool class="SynchronizationOnGetClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SynchronizationOnLocalVariableOrMethodParameter" enabled="false" level="WARNING" enabled_by_default="false">
<option name="reportLocalVariables" value="true" />
<option name="reportMethodParameters" value="true" />
</inspection_tool>
<inspection_tool class="SynchronizeOnNonFinalField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SynchronizeOnValueBasedClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SystemOutErr" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="SystemRunFinalizersOnExit" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TailRecursion" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="TextBlockBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="TextBlockMigration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TextLabelInSwitchStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThreadLocalSetWithNull" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ThreadWithDefaultRunMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowableNotThrown" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowablePrintStackTrace" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowablePrintedToSystemOut" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowableSupplierOnlyThrowException" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ToArrayCallWithZeroLengthArrayArgument" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TooBroadScope" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="m_allowConstructorAsInitializer" value="false" />
<option name="m_onlyLookAtBlocks" value="false" />
</inspection_tool>
<inspection_tool class="TrailingWhitespacesInTextBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialFunctionalExpressionUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialIf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialStringConcatenation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TryFinallyCanBeTryWithResources" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TryStatementWithMultipleResources" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="TryWithIdenticalCatches" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeParameterExtendsObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeParameterHidesVisibleType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UNCHECKED_WARNING" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UNUSED_IMPORT" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnaryPlus" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnclearBinaryExpression" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="UnnecessarilyQualifiedInnerClassAccess" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreReferencesNeedingImport" value="false" />
</inspection_tool>
<inspection_tool class="UnnecessaryBlockStatement" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreSwitchBranches" value="false" />
</inspection_tool>
<inspection_tool class="UnnecessaryBoxing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryBreak" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryCallToStringValueOf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryContinue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryDefault" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryEmptyArrayUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryFullyQualifiedName" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="m_ignoreJavadoc" value="false" />
<option name="ignoreInModuleStatements" value="true" />
</inspection_tool>
<inspection_tool class="UnnecessaryInitCause" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelOnBreakStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelOnContinueStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLocalVariable" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreImmediatelyReturnedVariables" value="false" />
<option name="m_ignoreAnnotatedVariables" value="false" />
</inspection_tool>
<inspection_tool class="UnnecessaryModifier" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryModuleDependencyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryParentheses" enabled="false" level="INFORMATION" enabled_by_default="false">
<option name="ignoreClarifyingParentheses" value="false" />
<option name="ignoreParenthesesOnConditionals" value="false" />
<option name="ignoreParenthesesOnLambdaParameter" value="false" />
</inspection_tool>
<inspection_tool class="UnnecessaryReturn" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryStringEscape" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryTemporaryOnConversionFromString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryTemporaryOnConversionToString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryToStringCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryUnaryMinus" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryUnboxing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryUnicodeEscape" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnpredictableBigDecimalConstructorCall" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreReferences" value="true" />
<option name="ignoreComplexLiterals" value="false" />
</inspection_tool>
<inspection_tool class="UnreachableCatch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnresolvedPropertyKey" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="UnsatisfiedRange" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnsupportedCharacter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnsupportedChronoFieldUnitCall" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_PREFIX_EXPRESSIONS" value="false" />
<option name="REPORT_POSTFIX_EXPRESSIONS" value="true" />
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
</inspection_tool>
<inspection_tool class="UnusedLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UseBulkOperation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UseCompareMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UseHashCodeMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="VarargParameter" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="VariableTypeCanBeExplicit" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="WaitWhileHoldingTwoLocks" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WhileCanBeDoWhile" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="WhileCanBeForeach" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WhileLoopSpinsOnField" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreNonEmtpyLoops" value="true" />
</inspection_tool>
<inspection_tool class="WrapperTypeMayBePrimitive" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WriteOnlyObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WrongPackageStatement" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="dependsOnMethodTestNG" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="groupsTestNG" enabled="false" level="WARNING" enabled_by_default="false">
<option name="groups">
<value>
<list size="0" />
</value>
</option>
</inspection_tool>
<inspection_tool class="unused" enabled="false" level="WARNING" enabled_by_default="false" checkParameterExcludingHierarchy="false">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
<option name="METHOD" value="true" />
<option name="CLASS" value="true" />
<option name="PARAMETER" value="true" />
<option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
<option name="ADD_SERVLET_TO_ENTRIES" value="true" />
<option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
</inspection_tool>
</profile>
</component>

View File

@@ -1,8 +1,8 @@
package org.toop.app;
import org.toop.app.game.Connect4Game;
import org.toop.app.game.ReversiGame;
import org.toop.app.game.TicTacToeGame;
import org.toop.app.game.Connect4GameThread;
import org.toop.app.game.ReversiGameThread;
import org.toop.app.game.TicTacToeGameThread;
import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.popup.ChallengePopup;
import org.toop.app.widget.popup.ErrorPopup;
@@ -131,11 +131,11 @@ public final class Server {
switch (type) {
case TICTACTOE ->
new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
new TicTacToeGameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
case REVERSI ->
new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
new ReversiGameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
case CONNECT4 ->
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
new Connect4GameThread(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
default -> new ErrorPopup("Unsupported game type.");
}
}

View File

@@ -6,6 +6,6 @@ import java.util.function.Consumer;
public class Connect4Canvas extends GameCanvas {
public Connect4Canvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, Color.TRANSPARENT, width, height, 7, 6, 10, true, onCellClicked,null);
super(color, Color.TRANSPARENT, width, height, 7, 6, 10, true, onCellClicked);
}
}

View File

@@ -35,8 +35,9 @@ public abstract class GameCanvas {
protected final boolean edges;
protected final Cell[] cells;
protected Cell currentCell;
protected GameCanvas(Color color, Color backgroundColor, int width, int height, int rowSize, int columnSize, int gapSize, boolean edges, Consumer<Integer> onCellClicked, Consumer<Integer> newCellEntered) {
protected GameCanvas(Color color, Color backgroundColor, int width, int height, int rowSize, int columnSize, int gapSize, boolean edges, Consumer<Integer> onCellClicked) {
canvas = new Canvas(width, height);
graphics = canvas.getGraphicsContext2D();
@@ -53,6 +54,7 @@ public abstract class GameCanvas {
this.edges = edges;
cells = new Cell[rowSize * columnSize];
currentCell = null;
final float cellWidth = ((float) width - gapSize * rowSize - gapSize) / rowSize;
final float cellHeight = ((float) height - gapSize * columnSize - gapSize) / columnSize;
@@ -82,12 +84,24 @@ public abstract class GameCanvas {
}
});
render();
}
public void setOnCellEntered(Consumer<Integer> onCellEntered) {
canvas.setOnMouseMoved(event -> {
final int column = (int) ((event.getX() / this.width) * rowSize);
final int row = (int) ((event.getY() / this.height) * columnSize);
final Cell cell = cells[column + row * rowSize];
if (currentCell != cell && cell.isInside(event.getX(), event.getY())) {
event.consume();
currentCell = cell;
onCellEntered.accept(column + row * rowSize);
}
});
}
private void render() {
graphics.setFill(backgroundColor);
graphics.fillRect(0, 0, width, height);

View File

@@ -7,61 +7,38 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
public final class ReversiCanvas extends GameCanvas {
private Move[] currentlyHighlightedMoves = null;
public ReversiCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked, Consumer<Integer> newCellEntered) {
super(color, new Color(0f,0.4f,0.2f,1f), width, height, 8, 8, 5, true, onCellClicked, newCellEntered);
private Move[] currentlyHighlightedMoves = null;
public ReversiCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, new Color(0f, 0.4f, 0.2f, 1f), width, height, 8, 8, 5, true, onCellClicked);
drawStartingDots();
final AtomicReference<Cell> lastHoveredCell = new AtomicReference<>(null);
canvas.setOnMouseMoved(event -> {
double mouseX = event.getX();
double mouseY = event.getY();
int cellId = -1;
Cell hovered = null;
for (Cell cell : cells) {
if (cell.isInside(mouseX, mouseY)) {
hovered = cell;
cellId = turnCoordsIntoCellId(mouseX, mouseY);
break;
}
}
Cell previous = lastHoveredCell.get();
if (hovered != previous) {
lastHoveredCell.set(hovered);
newCellEntered.accept(cellId);
}
});
}
public void setCurrentlyHighlightedMovesNull() {
currentlyHighlightedMoves = null;
}
public void setCurrentlyHighlightedMovesNull() {
currentlyHighlightedMoves = null;
}
public void drawHighlightDots(Move[] moves){
if (currentlyHighlightedMoves != null){
for (final Move move : currentlyHighlightedMoves){
Color color = move.value() == 'W'? Color.BLACK: Color.WHITE;
drawInnerDot(color, move.position(), true);
}
}
currentlyHighlightedMoves = moves;
if (moves != null) {
for (Move move : moves) {
Color color = move.value() == 'B' ? Color.BLACK : Color.WHITE;
drawInnerDot(color, move.position(), false);
}
}
}
public void drawHighlightDots(Move[] moves) {
if (currentlyHighlightedMoves != null) {
for (final Move move : currentlyHighlightedMoves) {
Color color = move.value() == 'W' ? Color.BLACK : Color.WHITE;
drawInnerDot(color, move.position(), true);
}
}
currentlyHighlightedMoves = moves;
if (moves != null) {
for (Move move : moves) {
Color color = move.value() == 'B' ? Color.BLACK : Color.WHITE;
drawInnerDot(color, move.position(), false);
}
}
}
private int turnCoordsIntoCellId(double x, double y) {
final int column = (int) ((x / this.width) * rowSize);
final int row = (int) ((y / this.height) * columnSize);
return column + row * rowSize;
}
private int turnCoordsIntoCellId(double x, double y) {
final int column = (int) ((x / this.width) * rowSize);
final int row = (int) ((y / this.height) * columnSize);
return column + row * rowSize;
}
public void drawStartingDots() {
drawDot(Color.BLACK, 28);
@@ -71,16 +48,14 @@ public final class ReversiCanvas extends GameCanvas {
}
public void drawLegalPosition(int cell, char player) {
Color innerColor;
Color innerColor;
if (player == 'B') {
innerColor = new Color(0.0f, 0.0f, 0.0f, 0.6f);
}
else {
innerColor = new Color(1.0f, 1.0f, 1.0f, 0.75f);
}
drawInnerDot(innerColor, cell,false);
public void drawLegalPosition(Color color, int cell) {
drawDot(new Color(color.getRed(), color.getGreen(), color.getBlue(), 0.25), cell);
if (player == 'B') {
innerColor = new Color(0.0f, 0.0f, 0.0f, 0.6f);
} else {
innerColor = new Color(1.0f, 1.0f, 1.0f, 0.75f);
}
drawInnerDot(innerColor, cell, false);
}
}

View File

@@ -6,7 +6,7 @@ import java.util.function.Consumer;
public final class TicTacToeCanvas extends GameCanvas {
public TicTacToeCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, Color.TRANSPARENT, width, height, 3, 3, 30, false, onCellClicked,null);
super(color, Color.TRANSPARENT, width, height, 3, 3, 30, false, onCellClicked);
}
public void drawX(Color color, int cell) {

View File

@@ -6,6 +6,7 @@ import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Game;
import org.toop.game.records.Move;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -18,7 +19,7 @@ public abstract class BaseGameThread<TGame extends Game, TAI, TCanvas> {
protected final GameInformation information;
protected final int myTurn;
protected final Runnable onGameOver;
protected final BlockingQueue<Game.Move> moveQueue;
protected final BlockingQueue<Move> moveQueue;
protected final TGame game;
protected final TAI ai;
@@ -27,6 +28,7 @@ public abstract class BaseGameThread<TGame extends Game, TAI, TCanvas> {
protected final TCanvas canvas;
protected final AtomicBoolean isRunning = new AtomicBoolean(true);
protected final AtomicBoolean isPaused = new AtomicBoolean(false);
protected BaseGameThread(
GameInformation information,
@@ -76,7 +78,7 @@ public abstract class BaseGameThread<TGame extends Game, TAI, TCanvas> {
}
private void onCellClicked(int cell) {
if (!isRunning.get()) return;
if (!isRunning.get() || isPaused.get()) return;
final int currentTurn = getCurrentTurn();
if (!information.players[currentTurn].isHuman) return;
@@ -84,8 +86,9 @@ public abstract class BaseGameThread<TGame extends Game, TAI, TCanvas> {
final char value = getSymbolForTurn(currentTurn);
try {
moveQueue.put(new Game.Move(cell, value));
} catch (InterruptedException _) {}
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {
}
}
protected void gameOver() {
@@ -110,10 +113,13 @@ public abstract class BaseGameThread<TGame extends Game, TAI, TCanvas> {
protected abstract void addCanvasToPrimary();
protected abstract int getCurrentTurn();
protected abstract char getSymbolForTurn(int turn);
protected abstract String getNameForTurn(int turn);
protected abstract void onMoveResponse(NetworkEvents.GameMoveResponse response);
protected abstract void onYourTurnResponse(NetworkEvents.YourTurnResponse response);
protected abstract void localGameThread();

View File

@@ -1,275 +0,0 @@
package org.toop.app.game;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.Connect4Canvas;
import org.toop.app.view.ViewStack;
import org.toop.app.view.views.GameView;
import org.toop.app.view.views.LocalMultiplayerView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Connect4.Connect4;
import org.toop.game.Connect4.Connect4AI;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
public class Connect4Game {
private final GameInformation information;
private final int myTurn;
private Runnable onGameOver;
private final BlockingQueue<Move> moveQueue;
private final Connect4 game;
private final Connect4AI ai;
private final int columnSize = 7;
private final int rowSize = 6;
private final GameView view;
private final Connect4Canvas canvas;
private final AtomicBoolean isRunning;
public Connect4Game(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
this.information = information;
this.myTurn = myTurn;
this.onGameOver = onGameOver;
moveQueue = new LinkedBlockingQueue<Move>();
game = new Connect4();
ai = new Connect4AI();
isRunning = new AtomicBoolean(true);
if (onForfeit == null || onExit == null) {
view = new GameView(null, () -> {
isRunning.set(false);
ViewStack.push(new LocalMultiplayerView(information));
}, null);
} else {
view = new GameView(onForfeit, () -> {
isRunning.set(false);
onExit.run();
}, onMessage);
}
canvas = new Connect4Canvas(Color.GRAY,
(App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,
(cell) -> {
if (onForfeit == null || onExit == null) {
if (information.players[game.getCurrentTurn()].isHuman) {
final char value = game.getCurrentTurn() == 0? 'X' : 'O';
try {
moveQueue.put(new Move(cell%columnSize, value));
} catch (InterruptedException _) {}
}
} else {
if (information.players[0].isHuman) {
final char value = myTurn == 0? 'X' : 'O';
try {
moveQueue.put(new Move(cell%columnSize, value));
} catch (InterruptedException _) {}
}
}
});
view.add(Pos.CENTER, canvas.getCanvas());
ViewStack.push(view);
if (onForfeit == null || onExit == null) {
new Thread(this::localGameThread).start();
setGameLabels(information.players[0].isHuman);
} else {
new EventFlow()
.listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse)
.listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse)
.listen(NetworkEvents.ReceivedMessage.class, this::onReceivedMessage);
setGameLabels(myTurn == 0);
}
updateCanvas();
}
public Connect4Game(GameInformation information) {
this(information, 0, null, null, null, null);
}
private void localGameThread() {
while (isRunning.get()) {
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "RED" : "BLUE";
final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount();
view.nextPlayer(information.players[currentTurn].isHuman,
information.players[currentTurn].name,
currentValue,
information.players[nextTurn].name);
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {}
} else {
final long start = System.currentTimeMillis();
move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty);
if (information.players[currentTurn].computerThinkTime > 0) {
final long elapsedTime = System.currentTimeMillis() - start;
final long sleepTime = Math.abs(information.players[currentTurn].computerThinkTime * 1000L - elapsedTime);
try {
Thread.sleep((long)(sleepTime * Math.random()));
} catch (InterruptedException _) {}
}
}
if (move == null) {
continue;
}
final GameState state = game.play(move);
updateCanvas();
/*
if (move.value() == 'X') {
canvas.drawX(Color.INDIANRED, move.position());
} else if (move.value() == 'O') {
canvas.drawO(Color.ROYALBLUE, move.position());
}
*/
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
view.gameOver(true, information.players[currentTurn].name);
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
}
isRunning.set(false);
}
}
}
private void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) {
return;
}
char playerChar;
if (response.player().equalsIgnoreCase(information.players[0].name)) {
playerChar = myTurn == 0? 'X' : 'O';
} else {
playerChar = myTurn == 0? 'O' : 'X';
}
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
view.gameOver(true, information.players[0].name);
gameOver();
} else {
view.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
gameOver();
}
}
if (move.value() == 'X') {
canvas.drawDot(Color.INDIANRED, move.position());
} else if (move.value() == 'O') {
canvas.drawDot(Color.ROYALBLUE, move.position());
}
updateCanvas();
setGameLabels(game.getCurrentTurn() == myTurn);
}
private void gameOver() {
if (onGameOver == null){
return;
}
isRunning.set(false);
onGameOver.run();
}
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
if (!isRunning.get()) {
return;
}
moveQueue.clear();
int position = -1;
if (information.players[0].isHuman) {
try {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
}
new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position))
.postEvent();
}
private void onReceivedMessage(NetworkEvents.ReceivedMessage msg) {
if (!isRunning.get()) {
return;
}
view.updateChat(msg.message());
}
private void updateCanvas() {
canvas.clearAll();
for (int i = 0; i < game.getBoard().length; i++) {
if (game.getBoard()[i] == 'X') {
canvas.drawDot(Color.RED, i);
} else if (game.getBoard()[i] == 'O') {
canvas.drawDot(Color.BLUE, i);
}
}
}
private void setGameLabels(boolean isMe) {
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "RED" : "BLUE";
view.nextPlayer(isMe,
information.players[isMe? 0 : 1].name,
currentValue,
information.players[isMe? 1 : 0].name);
}
}

View File

@@ -0,0 +1,188 @@
package org.toop.app.game;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.Connect4Canvas;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Connect4.Connect4;
import org.toop.game.Connect4.Connect4AI;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import java.util.function.Consumer;
public final class Connect4GameThread extends BaseGameThread<Connect4, Connect4AI, Connect4Canvas> {
private static final int COLS = 7;
public Connect4GameThread(
GameInformation info,
int myTurn,
Runnable onForfeit,
Runnable onExit,
Consumer<String> onMessage,
Runnable onGameOver
) {
super(
info,
myTurn,
onForfeit,
onExit,
onMessage,
onGameOver,
Connect4::new,
Connect4AI::new,
clickHandler -> new Connect4Canvas(
Color.GRAY,
(App.getHeight() / 4) * 3,
(App.getHeight() / 4) * 3,
cell -> clickHandler.accept(cell % COLS)
)
);
}
public Connect4GameThread(GameInformation info) {
this(info, 0, null, null, null, null);
}
@Override
protected void addCanvasToPrimary() {
primary.add(Pos.CENTER, canvas.getCanvas());
}
@Override
protected int getCurrentTurn() {
return game.getCurrentTurn();
}
@Override
protected char getSymbolForTurn(int turn) {
return turn == 0 ? 'X' : 'O';
}
@Override
protected String getNameForTurn(int turn) {
return turn == 0 ? "RED" : "BLUE";
}
private void drawMove(Move move) {
if (move.value() == 'X')
canvas.drawDot(Color.RED, move.position());
else
canvas.drawDot(Color.BLUE, move.position());
}
@Override
protected void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) return;
char symbol =
response.player().equalsIgnoreCase(information.players[0].name)
? (myTurn == 0 ? 'X' : 'O')
: (myTurn == 0 ? 'O' : 'X');
final Move move = new Move(Integer.parseInt(response.move()), symbol);
final GameState state = game.play(move);
drawMove(move);
updateCanvas();
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
boolean p0 = response.player().equalsIgnoreCase(information.players[0].name);
primary.gameOver(p0, information.players[p0 ? 0 : 1].name);
gameOver();
} else if (state == GameState.DRAW) {
primary.gameOver(false, "");
gameOver();
}
}
setGameLabels(game.getCurrentTurn() == myTurn);
}
@Override
protected void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
if (!isRunning.get()) return;
moveQueue.clear();
int col = -1;
if (information.players[0].isHuman) {
try {
col = moveQueue.take().position();
} catch (InterruptedException _) {
}
} else {
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
col = move.position();
}
new EventFlow()
.addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short) col))
.postEvent();
}
@Override
protected void localGameThread() {
while (isRunning.get()) {
final int current = game.getCurrentTurn();
setGameLabels(current == myTurn);
Move move = null;
if (information.players[current].isHuman) {
try {
final Move wants = moveQueue.take();
for (final Move legal : game.getLegalMoves()) {
if (legal.position() == wants.position() &&
legal.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {
}
} else {
final long start = System.currentTimeMillis();
move = ai.findBestMove(game, information.players[current].computerDifficulty);
if (information.players[current].computerThinkTime > 0) {
long elapsed = System.currentTimeMillis() - start;
long sleep = information.players[current].computerThinkTime * 1000L - elapsed;
try {
Thread.sleep((long) (sleep * Math.random()));
} catch (InterruptedException _) {
}
}
}
if (move == null) continue;
GameState state = game.play(move);
drawMove(move);
updateCanvas();
if (state != GameState.NORMAL) {
if (state == GameState.WIN)
primary.gameOver(information.players[current].isHuman, information.players[current].name);
else if (state == GameState.DRAW)
primary.gameOver(false, "");
isRunning.set(false);
}
}
}
private void updateCanvas() {
canvas.clearAll();
for (int i = 0; i < game.getBoard().length; i++) {
char c = game.getBoard()[i];
if (c == 'X') canvas.drawDot(Color.RED, i);
else if (c == 'O') canvas.drawDot(Color.BLUE, i);
}
}
}

View File

@@ -1,327 +0,0 @@
package org.toop.app.game;
import javafx.animation.SequentialTransition;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.ReversiCanvas;
import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.reversi.Reversi;
import org.toop.game.reversi.ReversiAI;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import java.awt.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
public final class ReversiGame {
private final GameInformation information;
private final int myTurn;
private final Runnable onGameOver;
private final BlockingQueue<Game.Move> moveQueue;
private Runnable onGameOver;
private final BlockingQueue<Move> moveQueue;
private final Reversi game;
private final ReversiAI ai;
private final GameView primary;
private final ReversiCanvas canvas;
private final AtomicBoolean isRunning;
private final AtomicBoolean isPaused;
public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
this.information = information;
this.myTurn = myTurn;
this.onGameOver = onGameOver;
moveQueue = new LinkedBlockingQueue<>();
game = new Reversi();
ai = new ReversiAI();
isRunning = new AtomicBoolean(true);
isPaused = new AtomicBoolean(false);
if (onForfeit == null || onExit == null) {
primary = new GameView(null, () -> {
isRunning.set(false);
WidgetContainer.getCurrentView().transitionPrevious();
}, null);
} else {
primary = new GameView(onForfeit, () -> {
isRunning.set(false);
onExit.run();
}, onMessage);
}
canvas = new ReversiCanvas(Color.BLACK,
(App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,
(cell) -> {
if (onForfeit == null || onExit == null) {
if (information.players[game.getCurrentTurn()].isHuman) {
final char value = game.getCurrentTurn() == 0? 'B' : 'W';
try {
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
} else {
if (information.players[0].isHuman) {
final char value = myTurn == 0? 'B' : 'W';
try {
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
}
},this::highlightCells);
primary.add(Pos.CENTER, canvas.getCanvas());
WidgetContainer.getCurrentView().transitionNext(primary);
if (onForfeit == null || onExit == null) {
new Thread(this::localGameThread).start();
setGameLabels(information.players[0].isHuman);
} else {
new EventFlow()
.listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse)
.listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse);
setGameLabels(myTurn == 0);
}
updateCanvas(false);
}
public ReversiGame(GameInformation information) {
this(information, 0, null, null, null,null);
}
private void localGameThread() {
while (isRunning.get()) {
if (isPaused.get()) {
try {
Thread.sleep(200);
} catch (InterruptedException _) {}
continue;
}
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "BLACK" : "WHITE";
final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount();
primary.nextPlayer(information.players[currentTurn].isHuman,
information.players[currentTurn].name,
currentValue,
information.players[nextTurn].name);
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {}
} else {
final long start = System.currentTimeMillis();
move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty);
if (information.players[currentTurn].computerThinkTime > 0) {
final long elapsedTime = System.currentTimeMillis() - start;
final long sleepTime = information.players[currentTurn].computerThinkTime * 1000L - elapsedTime;
try {
Thread.sleep((long) (sleepTime * Math.random()));
} catch (InterruptedException _) {}
}
}
if (move == null) {
continue;
}
canvas.setCurrentlyHighlightedMovesNull();
final GameState state = game.play(move);
updateCanvas(true);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
primary.gameOver(true, information.players[currentTurn].name);
} else if (state == Game.State.DRAW) {
primary.gameOver(false, "");
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
view.gameOver(true, information.players[currentTurn].name);
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
}
isRunning.set(false);
}
}
}
private void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) {
return;
}
char playerChar;
if (response.player().equalsIgnoreCase(information.players[0].name)) {
playerChar = myTurn == 0? 'B' : 'W';
} else {
playerChar = myTurn == 0? 'W' : 'B';
}
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
primary.gameOver(true, information.players[0].name);
gameOver();
} else {
primary.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == GameState.DRAW) {
view.gameOver(false, "");
game.play(move);
}
}
updateCanvas(false);
setGameLabels(game.getCurrentTurn() == myTurn);
}
private void gameOver() {
if (onGameOver == null){
return;
}
isRunning.set(false);
onGameOver.run();
}
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
if (!isRunning.get()) {
return;
}
moveQueue.clear();
int position = -1;
if (information.players[0].isHuman) {
try {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
}
new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short) position))
.postEvent();
}
private void updateCanvas(boolean animate) {
// Todo: this is very inefficient. still very fast but if the grid is bigger it might cause issues. improve.
canvas.clearAll();
for (int i = 0; i < game.getBoard().length; i++) {
if (game.getBoard()[i] == 'B') {
canvas.drawDot(Color.BLACK, i);
} else if (game.getBoard()[i] == 'W') {
canvas.drawDot(Color.WHITE, i);
}
}
final Move[] flipped = game.getMostRecentlyFlippedPieces();
final SequentialTransition animation = new SequentialTransition();
isPaused.set(true);
final Color fromColor = game.getCurrentPlayer() == 'W'? Color.WHITE : Color.BLACK;
final Color toColor = game.getCurrentPlayer() == 'W'? Color.BLACK : Color.WHITE;
if (animate && flipped != null) {
for (final Move flip : flipped) {
canvas.clear(flip.position());
canvas.drawDot(fromColor, flip.position());
animation.getChildren().addFirst(canvas.flipDot(fromColor, toColor, flip.position()));
}
}
animation.setOnFinished(_ -> {
isPaused.set(false);
final Move[] legalMoves = game.getLegalMoves();
for (final Move legalMove : legalMoves) {
canvas.drawLegalPosition(legalMove.position(), game.getCurrentPlayer());
for (final Game.Move legalMove : legalMoves) {
canvas.drawLegalPosition(fromColor, legalMove.position());
}
});
animation.play();
}
private void setGameLabels(boolean isMe) {
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "BLACK" : "WHITE";
primary.nextPlayer(isMe,
information.players[isMe? 0 : 1].name,
currentValue,
information.players[isMe? 1 : 0].name);
}
private void highlightCells(int cellEntered) {
Move[] legalMoves = game.getLegalMoves();
boolean isLegalMove = false;
for (Move move : legalMoves) {
if (move.position() == cellEntered){
isLegalMove = true;
break;
}
}
if (cellEntered >= 0){
Move[] moves = null;
if (isLegalMove) {
moves = game.getFlipsForPotentialMove(
new Point(cellEntered%game.getColumnSize(),cellEntered/game.getRowSize()),
game.getCurrentPlayer());
}
canvas.drawHighlightDots(moves);
}
}
}

View File

@@ -0,0 +1,241 @@
package org.toop.app.game;
import javafx.animation.SequentialTransition;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.ReversiCanvas;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.reversi.Reversi;
import org.toop.game.reversi.ReversiAI;
import java.awt.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
public final class ReversiGameThread extends BaseGameThread<Reversi, ReversiAI, ReversiCanvas> {
public ReversiGameThread(GameInformation info, int myTurn,
Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
super(info, myTurn, onForfeit, onExit, onMessage, onGameOver,
Reversi::new,
ReversiAI::new,
clickHandler -> new ReversiCanvas(
Color.BLACK,
(App.getHeight() / 4) * 3,
(App.getHeight() / 4) * 3,
clickHandler
)
);
canvas.setOnCellEntered(this::highlightCells);
}
public ReversiGameThread(GameInformation info) {
this(info, 0, null, null, null, null);
}
@Override
protected void addCanvasToPrimary() {
primary.add(Pos.CENTER, canvas.getCanvas());
}
@Override
protected int getCurrentTurn() {
return game.getCurrentTurn();
}
@Override
protected char getSymbolForTurn(int turn) {
return turn == 0 ? 'B' : 'W';
}
@Override
protected String getNameForTurn(int turn) {
return turn == 0 ? "BLACK" : "WHITE";
}
private void drawMove(Move move) {
if (move.value() == 'B') canvas.drawDot(Color.BLACK, move.position());
else canvas.drawDot(Color.WHITE, move.position());
}
@Override
protected void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) return;
char playerChar =
response.player().equalsIgnoreCase(information.players[0].name)
? (myTurn == 0 ? 'B' : 'W')
: (myTurn == 0 ? 'W' : 'B');
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
updateCanvas(true);
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
boolean p0 = response.player().equalsIgnoreCase(information.players[0].name);
primary.gameOver(p0, information.players[p0 ? 0 : 1].name);
gameOver();
} else if (state == GameState.DRAW) {
primary.gameOver(false, "");
gameOver();
}
}
setGameLabels(game.getCurrentTurn() == myTurn);
}
@Override
protected void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
if (!isRunning.get()) return;
moveQueue.clear();
int position = -1;
if (information.players[0].isHuman) {
try {
position = moveQueue.take().position();
} catch (InterruptedException _) {
}
} else {
final Move move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
}
new EventFlow()
.addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short) position))
.postEvent();
}
@Override
protected void localGameThread() {
while (isRunning.get()) {
if (isPaused.get()) {
try {
Thread.sleep(200);
} catch (InterruptedException _) {}
continue;
}
final int currentTurn = game.getCurrentTurn();
setGameLabels(currentTurn == myTurn);
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {
}
} else {
long start = System.currentTimeMillis();
move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty);
if (information.players[currentTurn].computerThinkTime > 0) {
long elapsed = System.currentTimeMillis() - start;
long sleep = information.players[currentTurn].computerThinkTime * 1000L - elapsed;
try {
Thread.sleep((long) (sleep * Math.random()));
} catch (InterruptedException _) {
}
}
}
if (move == null) continue;
GameState state = game.play(move);
updateCanvas(true);
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
primary.gameOver(information.players[currentTurn].isHuman,
information.players[currentTurn].name);
} else if (state == GameState.DRAW) {
primary.gameOver(false, "");
}
isRunning.set(false);
}
}
}
private void updateCanvas(boolean animate) {
canvas.clearAll();
for (int i = 0; i < game.getBoard().length; i++) {
char c = game.getBoard()[i];
if (c == 'B') canvas.drawDot(Color.BLACK, i);
else if (c == 'W') canvas.drawDot(Color.WHITE, i);
}
final Move[] flipped = game.getMostRecentlyFlippedPieces();
final SequentialTransition anim = new SequentialTransition();
isPaused.set(true);
final Color from = game.getCurrentPlayer() == 'W' ? Color.WHITE : Color.BLACK;
final Color to = game.getCurrentPlayer() == 'W' ? Color.BLACK : Color.WHITE;
if (animate && flipped != null) {
for (final Move flip : flipped) {
canvas.clear(flip.position());
canvas.drawDot(from, flip.position());
anim.getChildren().addFirst(canvas.flipDot(from, to, flip.position()));
}
}
anim.setOnFinished(_ -> {
isPaused.set(false);
for (final Move m : game.getLegalMoves()) {
canvas.drawLegalPosition(m.position(), game.getCurrentPlayer());
}
});
anim.play();
}
private void highlightCells(int cell) {
Move[] legal = game.getLegalMoves();
boolean isLegal = false;
for (Move m : legal) {
if (m.position() == cell) {
isLegal = true;
break;
}
}
if (cell >= 0) {
Move[] flips = null;
if (isLegal) {
flips = game.getFlipsForPotentialMove(
new Point(cell % game.getColumnSize(), cell / game.getRowSize()),
game.getCurrentPlayer()
);
}
canvas.drawHighlightDots(flips);
}
}
}

View File

@@ -1,250 +0,0 @@
package org.toop.app.game;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.TicTacToeCanvas;
import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.view.GameView;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.tictactoe.TicTacToe;
import org.toop.game.tictactoe.TicTacToeAI;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
public final class TicTacToeGame {
private final GameInformation information;
private final int myTurn;
private Runnable onGameOver;
private final BlockingQueue<Move> moveQueue;
private final TicTacToe game;
private final TicTacToeAI ai;
private final GameView primary;
private final TicTacToeCanvas canvas;
private final AtomicBoolean isRunning;
public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
this.information = information;
this.myTurn = myTurn;
this.onGameOver = onGameOver;
moveQueue = new LinkedBlockingQueue<Move>();
game = new TicTacToe();
ai = new TicTacToeAI();
isRunning = new AtomicBoolean(true);
if (onForfeit == null || onExit == null) {
primary = new GameView(null, () -> {
isRunning.set(false);
WidgetContainer.getCurrentView().transitionPrevious();
}, null);
} else {
primary = new GameView(onForfeit, () -> {
isRunning.set(false);
onExit.run();
}, onMessage);
}
canvas = new TicTacToeCanvas(Color.GRAY,
(App.getHeight() / 4) * 3, (App.getHeight() / 4) * 3,
(cell) -> {
if (onForfeit == null || onExit == null) {
if (information.players[game.getCurrentTurn()].isHuman) {
final char value = game.getCurrentTurn() == 0? 'X' : 'O';
try {
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
} else {
if (information.players[0].isHuman) {
final char value = myTurn == 0? 'X' : 'O';
try {
moveQueue.put(new Move(cell, value));
} catch (InterruptedException _) {}
}
}
});
primary.add(Pos.CENTER, canvas.getCanvas());
WidgetContainer.getCurrentView().transitionNext(primary);
if (onForfeit == null || onExit == null) {
new Thread(this::localGameThread).start();
} else {
new EventFlow()
.listen(NetworkEvents.GameMoveResponse.class, this::onMoveResponse)
.listen(NetworkEvents.YourTurnResponse.class, this::onYourTurnResponse);
setGameLabels(myTurn == 0);
}
}
public TicTacToeGame(GameInformation information) {
this(information, 0, null, null, null, null);
}
private void localGameThread() {
while (isRunning.get()) {
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "X" : "O";
final int nextTurn = (currentTurn + 1) % information.type.getPlayerCount();
primary.nextPlayer(information.players[currentTurn].isHuman,
information.players[currentTurn].name,
currentValue,
information.players[nextTurn].name);
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {}
} else {
final long start = System.currentTimeMillis();
move = ai.findBestMove(game, information.players[currentTurn].computerDifficulty);
if (information.players[currentTurn].computerThinkTime > 0) {
final long elapsedTime = System.currentTimeMillis() - start;
final long sleepTime = information.players[currentTurn].computerThinkTime * 1000L - elapsedTime;
try {
Thread.sleep((long)(sleepTime * Math.random()));
} catch (InterruptedException _) {}
}
}
if (move == null) {
continue;
}
final GameState state = game.play(move);
if (move.value() == 'X') {
canvas.drawX(Color.INDIANRED, move.position());
} else if (move.value() == 'O') {
canvas.drawO(Color.ROYALBLUE, move.position());
}
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
primary.gameOver(true, information.players[currentTurn].name);
} else if (state == GameState.DRAW) {
primary.gameOver(false, "");
}
isRunning.set(false);
}
}
}
private void onMoveResponse(NetworkEvents.GameMoveResponse response) {
if (!isRunning.get()) {
return;
}
char playerChar;
if (response.player().equalsIgnoreCase(information.players[0].name)) {
playerChar = myTurn == 0? 'X' : 'O';
} else {
playerChar = myTurn == 0? 'O' : 'X';
}
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
primary.gameOver(true, information.players[0].name);
gameOver();
} else {
primary.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == GameState.DRAW) {
if(game.getLegalMoves().length == 0) { //only return draw in online multiplayer if the game is actually over.
primary.gameOver(false, "");
gameOver();
}
}
}
if (move.value() == 'X') {
canvas.drawX(Color.RED, move.position());
} else if (move.value() == 'O') {
canvas.drawO(Color.BLUE, move.position());
}
setGameLabels(game.getCurrentTurn() == myTurn);
}
private void gameOver() {
if (onGameOver == null){
return;
}
isRunning.set(false);
onGameOver.run();
}
private void onYourTurnResponse(NetworkEvents.YourTurnResponse response) {
if (!isRunning.get()) {
return;
}
moveQueue.clear();
int position = -1;
if (information.players[0].isHuman) {
try {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} else {
final Move move;
move = ai.findBestMove(game, information.players[0].computerDifficulty);
assert move != null;
position = move.position();
}
new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position))
.postEvent();
}
private void setGameLabels(boolean isMe) {
final int currentTurn = game.getCurrentTurn();
final String currentValue = currentTurn == 0? "X" : "O";
primary.nextPlayer(isMe,
information.players[isMe? 0 : 1].name,
currentValue,
information.players[isMe? 1 : 0].name);
}
}

View File

@@ -1,19 +1,19 @@
package org.toop.app.game;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.TicTacToeCanvas;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.game.Game;
import org.toop.game.enumerators.GameState;
import org.toop.game.records.Move;
import org.toop.game.tictactoe.TicTacToe;
import org.toop.game.tictactoe.TicTacToeAI;
import java.util.function.Consumer;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacToeAI, TicTacToeCanvas> {
public TicTacToeGameThread(GameInformation info, int myTurn, Runnable onForfeit, Runnable onExit, Consumer<String> onMessage, Runnable onGameOver) {
super(info, myTurn, onForfeit, onExit, onMessage, onGameOver,
@@ -47,7 +47,7 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
return turn == 0 ? "X" : "O";
}
private void drawMove(Game.Move move) {
private void drawMove(Move move) {
if (move.value() == 'X') canvas.drawX(Color.RED, move.position());
else canvas.drawO(Color.BLUE, move.position());
}
@@ -61,16 +61,16 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
char playerChar;
if (response.player().equalsIgnoreCase(information.players[0].name)) {
playerChar = myTurn == 0? 'X' : 'O';
playerChar = myTurn == 0 ? 'X' : 'O';
} else {
playerChar = myTurn == 0? 'O' : 'X';
playerChar = myTurn == 0 ? 'O' : 'X';
}
final Game.Move move = new Game.Move(Integer.parseInt(response.move()), playerChar);
final Game.State state = game.play(move);
final Move move = new Move(Integer.parseInt(response.move()), playerChar);
final GameState state = game.play(move);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
if (response.player().equalsIgnoreCase(information.players[0].name)) {
primary.gameOver(true, information.players[0].name);
gameOver();
@@ -78,7 +78,7 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
primary.gameOver(false, information.players[1].name);
gameOver();
}
} else if (state == Game.State.DRAW) {
} else if (state == GameState.DRAW) {
if (game.getLegalMoves().length == 0) {
primary.gameOver(false, "");
gameOver();
@@ -103,12 +103,13 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
if (information.players[0].isHuman) {
try {
position = moveQueue.take().position();
} catch (InterruptedException _) {}
} catch (InterruptedException _) {
}
} else {
final Game.Move move;
final Move move;
if (information.players[1].name.equalsIgnoreCase("pism")) {
move = ai.findWorstMove(game,9);
}else{
move = ai.findWorstMove(game, 9);
} else {
move = ai.findBestMove(game, information.players[0].computerDifficulty);
}
@@ -116,7 +117,7 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
position = move.position();
}
new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short)position))
new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(), (short) position))
.postEvent();
}
@@ -126,21 +127,22 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
final int currentTurn = game.getCurrentTurn();
setGameLabels(currentTurn == myTurn);
Game.Move move = null;
Move move = null;
if (information.players[currentTurn].isHuman) {
try {
final Game.Move wants = moveQueue.take();
final Game.Move[] legalMoves = game.getLegalMoves();
final Move wants = moveQueue.take();
final Move[] legalMoves = game.getLegalMoves();
for (final Game.Move legalMove : legalMoves) {
for (final Move legalMove : legalMoves) {
if (legalMove.position() == wants.position() &&
legalMove.value() == wants.value()) {
legalMove.value() == wants.value()) {
move = wants;
break;
}
}
} catch (InterruptedException _) {}
} catch (InterruptedException _) {
}
} else {
final long start = System.currentTimeMillis();
@@ -151,8 +153,9 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
final long sleepTime = information.players[currentTurn].computerThinkTime * 1000L - elapsedTime;
try {
Thread.sleep((long)(sleepTime * Math.random()));
} catch (InterruptedException _) {}
Thread.sleep((long) (sleepTime * Math.random()));
} catch (InterruptedException _) {
}
}
}
@@ -160,13 +163,13 @@ public final class TicTacToeGameThread extends BaseGameThread<TicTacToe, TicTacT
continue;
}
final Game.State state = game.play(move);
final GameState state = game.play(move);
drawMove(move);
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
if (state != GameState.NORMAL) {
if (state == GameState.WIN) {
primary.gameOver(information.players[currentTurn].isHuman, information.players[currentTurn].name);
} else if (state == Game.State.DRAW) {
} else if (state == GameState.DRAW) {
primary.gameOver(false, "");
}

View File

@@ -1,400 +0,0 @@
package org.toop.app.view;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Separator;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import java.util.HashMap;
import java.util.Map;
public abstract class View {
private final boolean mainView;
private final StackPane view;
private final Map<String, Node> nodeMap;
protected View(boolean mainView, String cssClass) {
this.mainView = mainView;
view = new StackPane();
view.getStyleClass().add(cssClass);
nodeMap = new HashMap<String, Node>();
}
public void add(Pos position, Node node) {
assert node != null;
StackPane.setAlignment(node, position);
view.getChildren().add(node);
}
protected Region hspacer() {
final Region hspacer = new Region();
hspacer.getStyleClass().add("hspacer");
return hspacer;
}
protected Region vspacer() {
final Region vspacer = new Region();
vspacer.getStyleClass().add("vspacer");
return vspacer;
}
protected ScrollPane fit(String identifier, String cssClass, Node node) {
assert node != null;
final ScrollPane fit = new ScrollPane(node);
fit.getStyleClass().add(cssClass);
fit.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
fit.setFitToWidth(true);
fit.setFitToHeight(true);
if (!identifier.isEmpty()) {
nodeMap.put(identifier, fit);
}
return fit;
}
protected ScrollPane fit(String identifier, Node node) {
return fit(identifier, "fit", node);
}
protected ScrollPane fit(Node node) {
return fit("", node);
}
protected HBox hbox(String identifier, String cssClass, Node... nodes) {
assert !nodeMap.containsKey(identifier);
final HBox hbox = new HBox();
hbox.getStyleClass().add(cssClass);
hbox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
for (final Node node : nodes) {
if (node != null) {
hbox.getChildren().add(node);
}
}
if (!identifier.isEmpty()) {
nodeMap.put(identifier, hbox);
}
return hbox;
}
protected HBox hbox(String identifier, Node... nodes) {
return hbox(identifier, "container", nodes);
}
protected HBox hbox(Node... nodes) {
return hbox("", nodes);
}
protected HBox hboxFill(String identifier, String cssClass, Node... nodes) {
final HBox hbox = hbox(identifier, cssClass, nodes);
for (final Node node : hbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxHeight(Double.MAX_VALUE);
}
}
return hbox;
}
protected HBox hboxFill(String identifier, Node... nodes) {
final HBox hbox = hbox(identifier, nodes);
for (final Node node : hbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxHeight(Double.MAX_VALUE);
}
}
return hbox;
}
protected HBox hboxFill(Node... nodes) {
final HBox hbox = hbox(nodes);
for (final Node node : hbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxHeight(Double.MAX_VALUE);
}
}
return hbox;
}
protected VBox vbox(String identifier, String cssClass, Node... nodes) {
assert !nodeMap.containsKey(identifier);
final VBox vbox = new VBox();
vbox.getStyleClass().add(cssClass);
vbox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
for (final Node node : nodes) {
if (node != null) {
vbox.getChildren().add(node);
}
}
if (!identifier.isEmpty()) {
nodeMap.put(identifier, vbox);
}
return vbox;
}
protected VBox vbox(String identifier, Node... nodes) {
return vbox(identifier, "container", nodes);
}
protected VBox vbox(Node... nodes) {
return vbox("", nodes);
}
protected VBox vboxFill(String identifier, String cssClass, Node... nodes) {
final VBox vbox = vbox(identifier, cssClass, nodes);
for (final Node node : vbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxWidth(Double.MAX_VALUE);
}
}
return vbox;
}
protected VBox vboxFill(String identifier, Node... nodes) {
final VBox vbox = vbox(identifier, nodes);
for (final Node node : vbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxWidth(Double.MAX_VALUE);
}
}
return vbox;
}
protected VBox vboxFill(Node... nodes) {
final VBox vbox = vbox(nodes);
for (final Node node : vbox.getChildren()) {
if (node instanceof Region) {
((Region)node).setMaxWidth(Double.MAX_VALUE);
}
}
return vbox;
}
protected Separator separator(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final Separator separator = new Separator();
separator.getStyleClass().add(cssClass);
if (!identifier.isEmpty()) {
nodeMap.put(identifier, separator);
}
return separator;
}
protected Separator separator(String identifier) {
return separator(identifier, "separator");
}
protected Separator separator() {
return separator("");
}
protected Text header(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final Text header = new Text();
header.getStyleClass().add(cssClass);
if (!identifier.isEmpty()) {
nodeMap.put(identifier, header);
}
return header;
}
protected Text header(String identifier) {
return header(identifier, "header");
}
protected Text header() {
return header("");
}
protected Text text(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final Text text = new Text();
text.getStyleClass().add(cssClass);
if (!identifier.isEmpty()) {
nodeMap.put(identifier, text);
}
return text;
}
protected Text text(String identifier) {
return text(identifier, "text");
}
protected Text text() {
return text("");
}
protected Button button(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final Button button = new Button();
button.getStyleClass().add(cssClass);
button.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
if (!identifier.isEmpty()) {
nodeMap.put(identifier, button);
}
return button;
}
protected Button button(String identifier) {
return button(identifier, "button");
}
protected Button button() {
return button("");
}
protected Slider slider(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final Slider slider = new Slider();
slider.getStyleClass().add(cssClass);
slider.setMinorTickCount(0);
slider.setMajorTickUnit(1);
slider.setBlockIncrement(1);
slider.setSnapToTicks(true);
slider.setShowTickLabels(true);
slider.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
if (!identifier.isEmpty()) {
nodeMap.put(identifier, slider);
}
return slider;
}
protected Slider slider(String identifier) {
return slider(identifier, "slider");
}
protected Slider slider() {
return slider("");
}
protected TextField input(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final TextField input = new TextField();
input.getStyleClass().add(cssClass);
input.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
if (!identifier.isEmpty()) {
nodeMap.put(identifier, input);
}
return input;
}
protected TextField input(String identifier) {
return input(identifier, "input");
}
protected TextField input() {
return input("");
}
protected <T> ComboBox<T> combobox(String identifier, String cssClass) {
assert !nodeMap.containsKey(identifier);
final ComboBox<T> combobox = new ComboBox<T>();
combobox.getStyleClass().add(cssClass);
combobox.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
if (!identifier.isEmpty()) {
nodeMap.put(identifier, combobox);
}
return combobox;
}
protected <T> ComboBox<T> combobox(String identifier) {
return combobox(identifier, "combo-box");
}
protected <T> ComboBox<T> combobox() {
return combobox("");
}
@SuppressWarnings("unchecked")
protected <T extends Node> T get(String identifier) {
assert nodeMap.containsKey(identifier);
return (T) nodeMap.get(identifier);
}
protected void clear() {
view.getChildren().clear();
nodeMap.clear();
}
public boolean isMainView() { return mainView; }
public Region getView() { return view; }
public abstract void setup();
public void cleanup() {
clear();
}
}

View File

@@ -1,105 +0,0 @@
package org.toop.app.view;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import java.util.Stack;
public final class ViewStack {
private static boolean setup = false;
private static StackPane root;
private static View active;
private static Stack<View> stack;
public static void setup(Scene scene) {
assert scene != null;
if (setup) {
return;
}
root = new StackPane();
active = null;
stack = new Stack<View>();
scene.setRoot(root);
setup = true;
}
public static void cleanup() {
assert setup;
final var count = stack.size();
for (int i = 0; i < count; i++) {
pop();
}
if (active != null) {
active.cleanup();
}
setup = false;
}
public static void reload() {
assert setup;
for (final var view : stack) {
view.cleanup();
}
if (active != null) {
active.cleanup();
active.setup();
}
for (final var view : stack) {
view.setup();
}
}
public static void push(View view) {
assert setup;
assert view != null;
if (view.isMainView()) {
Platform.runLater(() -> {
if (active != null) {
root.getChildren().removeFirst();
active.cleanup();
}
root.getChildren().addFirst(view.getView());
view.setup();
active = view;
});
} else {
Platform.runLater(() -> {
stack.push(view);
root.getChildren().addLast(view.getView());
view.setup();
});
}
}
public static void pop() {
assert setup;
if (stack.isEmpty()) {
return;
}
Platform.runLater(() -> {
final var last = stack.pop();
root.getChildren().removeLast();
last.cleanup();
});
}
}

View File

@@ -1,129 +0,0 @@
package org.toop.app.view.displays;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import org.toop.app.widget.Widget;
import org.toop.framework.audio.AudioEventListener;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import javafx.geometry.Pos;
import javafx.scene.text.Text;
import org.toop.framework.eventbus.GlobalEventBus;
public class SongDisplay extends VBox implements Widget {
private final Text songTitle;
private final ProgressBar progressBar;
private final Text progressText;
private boolean paused = false;
public SongDisplay() {
new EventFlow()
.listen(this::updateTheSong);
setAlignment(Pos.CENTER);
getStyleClass().add("song-display");
songTitle = new Text("song playing");
songTitle.getStyleClass().add("song-title");
progressBar = new ProgressBar(0);
progressBar.getStyleClass().add("progress-bar");
progressText = new Text("0:00/0:00");
progressText.getStyleClass().add("progress-text");
Button skipButton = new Button(">>");
Button pauseButton = new Button("");
Button previousButton = new Button("<<");
skipButton.getStyleClass().setAll("skip-button");
pauseButton.getStyleClass().setAll("pause-button");
previousButton.getStyleClass().setAll("previous-button");
skipButton.setOnAction( event -> {
GlobalEventBus.post(new AudioEvents.SkipMusic());
paused = false;
pauseButton.setText(getPlayString(paused));
});
pauseButton.setOnAction(event -> {
GlobalEventBus.post(new AudioEvents.PauseMusic());
paused = !paused;
pauseButton.setText(getPlayString(paused));
});
previousButton.setOnAction( event -> {
GlobalEventBus.post(new AudioEvents.PreviousMusic());
paused = false;
pauseButton.setText(getPlayString(paused));
});
HBox control = new HBox(10, previousButton, pauseButton, skipButton);
control.setAlignment(Pos.CENTER);
control.getStyleClass().add("controls");
getChildren().addAll(songTitle, progressBar, progressText, control);
}
private void updateTheSong(AudioEvents.PlayingMusic event) {
Platform.runLater(() -> {
String text = event.name();
text = text.substring(0, text.length() - 4);
songTitle.setText(text);
double currentPos = event.currentPosition();
double duration = event.duration();
if (currentPos / duration > 0.05) {
double progress = currentPos / duration;
progressBar.setProgress(progress);
}
else if (currentPos / duration < 0.05) {
progressBar.setProgress(0.05);
}
progressText.setText(getTimeString(event.currentPosition(), event.duration()));
});
}
private String getTimeString(long position, long duration) {
long positionMinutes = position / 60;
long durationMinutes = duration / 60;
long positionSeconds = position % 60;
long durationSeconds = duration % 60;
String positionSecondsStr = String.valueOf(positionSeconds);
String durationSecondsStr = String.valueOf(durationSeconds);
if (positionSeconds < 10) {
positionSecondsStr = "0" + positionSeconds;
}
if (durationSeconds < 10) {
durationSecondsStr = "0" + durationSeconds;
}
String time = positionMinutes + ":" + positionSecondsStr + " / " + durationMinutes + ":" + durationSecondsStr;
return time;
}
private String getPlayString(boolean paused) {
if (paused) {
return "";
}
else {
return "";
}
}
@Override
public Node getNode() {
return this;
}
}

View File

@@ -1,127 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.GameInformation;
import org.toop.app.Server;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.text.Text;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public final class ChallengeView extends View {
private final GameInformation.Player playerInformation;
private final String challenger;
private final String game;
private final Consumer<GameInformation.Player> onAccept;
public ChallengeView(String challenger, String game, Consumer<GameInformation.Player> onAccept) {
super(false, "bg-popup");
playerInformation = new GameInformation.Player();
this.challenger = challenger;
this.game = game;
this.onAccept = onAccept;
}
@Override
public void setup() {
final Text challengeText = text();
challengeText.setText(AppContext.getString("you-were-challenged-by"));
final Text challengerHeader = header();
challengerHeader.setText(challenger);
final Text gameText = text();
gameText.setText(AppContext.getString("to-a-game-of") + " " + game);
final Button acceptButton = button();
acceptButton.setText(AppContext.getString("accept"));
acceptButton.setOnAction(_ -> {
onAccept.accept(playerInformation);
});
final Button denyButton = button();
denyButton.setText(AppContext.getString("deny"));
denyButton.setOnAction(_ -> {
ViewStack.pop();
});
final List<Node> nodes = new ArrayList<>();
if (playerInformation.isHuman) {
final Button playerToggle = button();
playerToggle.setText(AppContext.getString("player"));
playerToggle.setOnAction(_ -> {
playerInformation.isHuman = false;
cleanup();
setup();
});
nodes.add(vbox(playerToggle));
} else {
final Button computerToggle = button();
computerToggle.setText(AppContext.getString("computer"));
computerToggle.setOnAction(_ -> {
playerInformation.isHuman = true;
cleanup();
setup();
});
nodes.add(vbox(computerToggle));
final Text computerDifficultyText = text();
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
final Slider computerDifficultySlider = slider();
computerDifficultySlider.setMin(0);
computerDifficultySlider.setMax(Server.gameToType(game).getMaxDepth());
computerDifficultySlider.setValue(playerInformation.computerDifficulty);
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
playerInformation.computerDifficulty = newValue.intValue();
});
nodes.add(vbox(computerDifficultyText, computerDifficultySlider));
}
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit(hboxFill(
vboxFill(
challengeText,
challengerHeader,
gameText,
separator(),
hboxFill(
acceptButton,
denyButton
)
),
vboxFill(
nodes.toArray(new Node[0])
)
))
);
}
}

View File

@@ -1,110 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.App;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.util.Duration;
public final class CreditsView extends View {
public CreditsView() {
super(false, "bg-primary");
}
@Override
public void setup() {
final Text scrumMasterHeader = header();
scrumMasterHeader.setText(AppContext.getString("scrum-master") + ": Stef");
final Text productOwnerHeader = header();
productOwnerHeader.setText(AppContext.getString("product-owner") + ": Omar");
final Text mergeCommanderHeader = header();
mergeCommanderHeader.setText(AppContext.getString("merge-commander") + ": Bas");
final Text localizationHeader = header();
localizationHeader.setText(AppContext.getString("localization") + ": Ticho");
final Text aiHeader = header();
aiHeader.setText(AppContext.getString("ai") + ": Michiel");
final Text developersHeader = header();
developersHeader.setText(AppContext.getString("developers") + ": Michiel, Bas, Stef, Omar, Ticho");
final Text moralSupportHeader = header();
moralSupportHeader.setText(AppContext.getString("moral-support") + ": Wesley");
final Text openglHeader = header();
openglHeader.setText(AppContext.getString("opengl") + ": Omar");
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit("credits-fit", vboxFill("credits-container", "credits-container",
vbox("credits-spacer-top", ""),
scrumMasterHeader,
productOwnerHeader,
mergeCommanderHeader,
localizationHeader,
aiHeader,
developersHeader,
moralSupportHeader,
openglHeader,
vbox("credits-spacer-bottom", "")
))
);
final Button backButton = button();
backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.pop(); });
add(Pos.BOTTOM_LEFT,
vboxFill(
backButton
)
);
playCredits(100, 20);
}
private void playCredits(int lineHeight, int length) {
final ScrollPane creditsFit = get("credits-fit");
creditsFit.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
creditsFit.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
final VBox creditsContainer = get("credits-container");
creditsContainer.setSpacing(lineHeight);
final VBox creditsSpacerTop = get("credits-spacer-top");
creditsSpacerTop.setMinHeight(App.getHeight() - lineHeight);
final VBox creditsSpacerBottom = get("credits-spacer-bottom");
creditsSpacerBottom.setMinHeight(App.getHeight() - lineHeight);
final Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(0), new KeyValue(creditsFit.vvalueProperty(), 0.0)),
new KeyFrame(Duration.seconds(length), new KeyValue(creditsFit.vvalueProperty(), 1.0))
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
}

View File

@@ -1,45 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.text.Text;
public final class ErrorView extends View {
private final String error;
public ErrorView(String error) {
super(false, "bg-popup");
this.error = error;
}
@Override
public void setup() {
final Text errorHeader = header();
errorHeader.setText(AppContext.getString("error"));
final Text errorText = text();
errorText.setText(error);
final Button okButton = button();
okButton.setText(AppContext.getString("ok"));
okButton.setOnAction(_ -> { ViewStack.pop(); });
add(Pos.CENTER,
vboxFill(
errorHeader,
separator(),
vspacer(),
errorText,
vspacer(),
separator(),
okButton
)
);
}
}

View File

@@ -1,184 +0,0 @@
package org.toop.app.view.views;
import javafx.application.Platform;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.text.Text;
import java.util.function.Consumer;
public final class GameView extends View {
private static class GameOverView extends View {
private final boolean iWon;
private final String winner;
public GameOverView(boolean iWon, String winner) {
super(false, "bg-popup");
this.iWon = iWon;
this.winner = winner;
}
@Override
public void setup() {
final Text gameOverHeader = header();
gameOverHeader.setText(AppContext.getString("game-over"));
final Button okButton = button();
okButton.setText(AppContext.getString("ok"));
okButton.setOnAction(_ -> { ViewStack.pop(); });
Text gameOverText = text();
if (winner.isEmpty()) {
gameOverText.setText(AppContext.getString("the-game-ended-in-a-draw"));
} else {
if (iWon) {
gameOverText.setText(AppContext.getString("you-win") + " " + winner);
} else {
gameOverText.setText(AppContext.getString("you-lost-against") + " " + winner);
}
}
add(Pos.CENTER,
fit(vboxFill(
gameOverHeader,
separator(),
vspacer(),
gameOverText,
vspacer(),
separator(),
okButton
))
);
}
}
private final Button forfeitButton;
private final Button exitButton;
private final Text currentPlayerHeader;
private final Text currentMoveHeader;
private final Text nextPlayerHeader;
private final ListView<Text> chatListView;
private final TextField chatInput;
public GameView(Runnable onForfeit, Runnable onExit, Consumer<String> onMessage) {
assert onExit != null;
super(true, "bg-primary");
if (onForfeit != null) {
forfeitButton = button();
forfeitButton.setText(AppContext.getString("forfeit"));
forfeitButton.setOnAction(_ -> onForfeit.run());
} else {
forfeitButton = null;
}
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
if (onMessage != null) {
chatListView = new ListView<Text>();
chatInput = input();
chatInput.setOnAction(_ -> {
onMessage.accept(chatInput.getText());
chatInput.setText("");
});
} else {
chatListView = null;
chatInput = null;
}
exitButton = button();
exitButton.setText(AppContext.getString("exit"));
exitButton.setOnAction(_ -> onExit.run());
currentPlayerHeader = header("", "current-player");
currentMoveHeader = header();
nextPlayerHeader = header();
}
@Override
public void setup() {
add(Pos.TOP_RIGHT,
fit(vboxFill(
currentPlayerHeader,
hboxFill(
separator(),
currentMoveHeader,
separator()
),
nextPlayerHeader
))
);
add(Pos.BOTTOM_LEFT,
vboxFill(
forfeitButton,
exitButton
)
);
if (chatListView != null) {
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
chatListView,
chatInput
)
));
}
}
public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) {
Platform.runLater(() -> {
currentPlayerHeader.setText(currentPlayer);
currentMoveHeader.setText(currentMove);
nextPlayerHeader.setText(nextPlayer);
if (isMe) {
currentPlayerHeader.getStyleClass().add("my-turn");
} else {
currentPlayerHeader.getStyleClass().remove("my-turn");
}
});
}
public void updateChat(String message) {
if (chatListView == null) {
return;
}
final Text messageText = text();
messageText.setText(message);
chatListView.getItems().add(messageText);
}
public void gameOver(boolean iWon, String winner) {
ViewStack.push(new GameOverView(iWon, winner));
}
}

View File

@@ -1,171 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.GameInformation;
import org.toop.app.game.Connect4Game;
import org.toop.app.game.ReversiGame;
import org.toop.app.game.TicTacToeGameThread;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import java.util.ArrayList;
import java.util.List;
public final class LocalMultiplayerView extends View {
private final GameInformation information;
public LocalMultiplayerView(GameInformation information) {
super(true, "bg-primary");
this.information = information;
}
public LocalMultiplayerView(GameInformation.Type type) {
this(new GameInformation(type));
}
@Override
public void setup() {
final Button playButton = button();
playButton.setText(AppContext.getString("play"));
playButton.setOnAction(_ -> {
for (final GameInformation.Player player : information.players) {
if (player.name.isEmpty()) {
ViewStack.push(new ErrorView(AppContext.getString("please-enter-your-name")));
return;
}
}
switch (information.type) {
case TICTACTOE: new TicTacToeGameThread(information); break;
case REVERSI: new ReversiGame(information); break;
case CONNECT4: new Connect4Game(information); break;
// case BATTLESHIP: new BattleshipGame(information); break;
}
});
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit(vboxFill(
hbox(
setupPlayers()
),
separator(),
playButton
))
);
final Button backButton = button();
backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
add(Pos.BOTTOM_LEFT,
vboxFill(
backButton
)
);
}
private VBox[] setupPlayers() {
final VBox[] playerBoxes = new VBox[information.type.getPlayerCount()];
for (int i = 0; i < playerBoxes.length; i++) {
final int index = i;
List<Node> nodes = new ArrayList<>();
final Text playerHeader = header();
playerHeader.setText(AppContext.getString("player") + " #" + (i + 1));
nodes.add(playerHeader);
nodes.add(separator());
final Text nameText = text();
nameText.setText(AppContext.getString("name"));
if (information.players[i].isHuman) {
final Button playerToggle = button();
playerToggle.setText(AppContext.getString("player"));
playerToggle.setOnAction(_ -> {
information.players[index].isHuman = false;
cleanup();
setup();
});
nodes.add(vboxFill(playerToggle));
final TextField playerNameInput = input();
playerNameInput.setPromptText(AppContext.getString("enter-your-name"));
playerNameInput.setText(information.players[i].name);
playerNameInput.textProperty().addListener((_, _, newValue) -> {
information.players[index].name = newValue;
});
nodes.add(vboxFill(nameText, playerNameInput));
} else {
final Button computerToggle = button();
computerToggle.setText(AppContext.getString("computer"));
computerToggle.setOnAction(_ -> {
information.players[index].isHuman = true;
cleanup();
setup();
});
nodes.add(vboxFill(computerToggle));
information.players[i].name = "Pism Bot V" + i;
final Text computerNameText = text();
computerNameText.setText(information.players[index].name);
nodes.add(vboxFill(nameText, computerNameText));
final Text computerDifficultyText = text();
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
final Slider computerDifficultySlider = slider();
computerDifficultySlider.setMin(0);
computerDifficultySlider.setMax(information.type.getMaxDepth());
computerDifficultySlider.setValue(information.players[i].computerDifficulty);
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
information.players[index].computerDifficulty = newValue.intValue();
});
nodes.add(vboxFill(computerDifficultyText, computerDifficultySlider));
final Text computerThinkTimeText = text();
computerThinkTimeText.setText(AppContext.getString("computer-think-time"));
final Slider computerThinkTimeSlider = slider();
computerThinkTimeSlider.setMin(0);
computerThinkTimeSlider.setMax(5);
computerThinkTimeSlider.setValue(information.players[i].computerThinkTime);
computerThinkTimeSlider.valueProperty().addListener((_, _, newValue) -> {
information.players[index].computerThinkTime = newValue.intValue();
});
nodes.add(vboxFill(computerThinkTimeText, computerThinkTimeSlider));
}
playerBoxes[i] = vboxFill(nodes.toArray(new Node[0]));
}
return playerBoxes;
}
}

View File

@@ -1,57 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.GameInformation;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
public final class LocalView extends View {
public LocalView() {
super(true, "bg-primary");
}
@Override
public void setup() {
final Button ticTacToeButton = button();
ticTacToeButton.setText(AppContext.getString("tic-tac-toe"));
ticTacToeButton.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.TICTACTOE)); });
final Button reversiButton = button();
reversiButton.setText(AppContext.getString("reversi"));
reversiButton.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.REVERSI)); });
final Button connect4Button = button();
connect4Button.setText(AppContext.getString("connect4"));
connect4Button.setOnAction(_ -> { ViewStack.push(new LocalMultiplayerView(GameInformation.Type.CONNECT4)); });
add(Pos.CENTER,
fit(vboxFill(
ticTacToeButton,
reversiButton,
connect4Button
))
);
final Button backButton = button();
backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.BOTTOM_LEFT,
vboxFill(
backButton
)
);
}
}

View File

@@ -1,55 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.App;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.local.AppContext;
import org.toop.app.view.displays.SongDisplay;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
public final class MainView extends View {
public MainView() {
super(true, "bg-primary");
}
@Override
public void setup() {
final Button localButton = button();
localButton.setText(AppContext.getString("local"));
localButton.setOnAction(_ -> { ViewStack.push(new LocalView()); });
final Button onlineButton = button();
onlineButton.setText(AppContext.getString("online"));
onlineButton.setOnAction(_ -> { ViewStack.push(new OnlineView()); });
final Button creditsButton = button();
creditsButton.setText(AppContext.getString("credits"));
creditsButton.setOnAction(_ -> { ViewStack.push(new CreditsView()); });
final Button optionsButton = button();
optionsButton.setText(AppContext.getString("options"));
optionsButton.setOnAction(_ -> { ViewStack.push(new OptionsView()); });
final Button quitButton = button();
quitButton.setText(AppContext.getString("quit"));
quitButton.setOnAction(_ -> { App.startQuit(); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit(vboxFill(
localButton,
onlineButton,
creditsButton,
optionsButton,
quitButton
))
);
}
}

View File

@@ -1,91 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.Server;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.text.Text;
public class OnlineView extends View {
public OnlineView() {
super(true, "bg-primary");
}
@Override
public void setup() {
final Text serverInformationHeader = header();
serverInformationHeader.setText(AppContext.getString("server-information"));
final Text serverIPText = text();
serverIPText.setText(AppContext.getString("ip-address"));
final TextField serverIPInput = input();
serverIPInput.setPromptText(AppContext.getString("enter-the-server-ip"));
final Text serverPortText = text();
serverPortText.setText(AppContext.getString("port"));
final TextField serverPortInput = input();
serverPortInput.setPromptText(AppContext.getString("enter-the-server-port"));
final Text playerNameText = text();
playerNameText.setText(AppContext.getString("player-name"));
final TextField playerNameInput = input();
playerNameInput.setPromptText(AppContext.getString("enter-your-name"));
final Button connectButton = button();
connectButton.setText(AppContext.getString("connect"));
connectButton.setOnAction(_ -> {
new Server(serverIPInput.getText(), serverPortInput.getText(), playerNameInput.getText());
});
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit(vboxFill(
serverInformationHeader,
separator(),
vboxFill(
serverIPText,
serverIPInput
),
vboxFill(
serverPortText,
serverPortInput
),
vboxFill(
playerNameText,
playerNameInput
),
vboxFill(
connectButton
)
))
);
final Button backButton = button();
backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.push(new MainView()); });
add(Pos.BOTTOM_LEFT,
vboxFill(
backButton
)
);
}
}

View File

@@ -1,258 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.App;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.framework.audio.VolumeControl;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import org.toop.local.AppContext;
import org.toop.local.AppSettings;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Slider;
import javafx.scene.text.Text;
import javafx.util.StringConverter;
import java.util.Locale;
public final class OptionsView extends View {
public OptionsView() {
super(false, "bg-secondary");
}
@Override
public void setup() {
final Text generalHeader = header();
generalHeader.setText(AppContext.getString("general"));
final Text volumeHeader = header();
volumeHeader.setText(AppContext.getString("volume"));
final Text styleHeader = header();
styleHeader.setText(AppContext.getString("style"));
add(Pos.CENTER,
fit(hboxFill(
vboxFill(
generalHeader,
separator(),
vboxFill(
text("language-text"),
combobox("language-combobox")
),
vboxFill(
button("fullscreen-button")
)
),
vboxFill(
volumeHeader,
separator(),
vboxFill(
text("master-volume-text"),
slider("master-volume-slider")
),
vboxFill(
text("effects-volume-text"),
slider("effects-volume-slider")
),
vboxFill(
text("music-volume-text"),
slider("music-volume-slider")
)
),
vboxFill(
styleHeader,
separator(),
vboxFill(
text("theme-text"),
combobox("theme-combobox")
),
vboxFill(
text("layout-text"),
combobox("layout-combobox")
)
)
))
);
setupLanguageOption();
setupMasterVolumeOption();
setupEffectsVolumeOption();
setupMusicVolumeOption();
setupThemeOption();
setupLayoutOption();
setupFullscreenOption();
final Button backButton = button();
backButton.setText(AppContext.getString("back"));
backButton.setOnAction(_ -> { ViewStack.pop(); });
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.BOTTOM_LEFT,
vboxFill(
backButton
)
);
}
private void setupLanguageOption() {
final Text languageText = get("language-text");
languageText.setText(AppContext.getString("language"));
final ComboBox<Locale> languageCombobox = get("language-combobox");
languageCombobox.getItems().addAll(AppContext.getLocalization().getAvailableLocales());
languageCombobox.setValue(AppContext.getLocale());
languageCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setLocale(newValue.toString());
AppContext.setLocale(newValue);
});
languageCombobox.setConverter(new StringConverter<>() {
@Override
public String toString(Locale locale) {
return AppContext.getString(locale.getDisplayName().toLowerCase());
}
@Override
public Locale fromString(String s) {
return null;
}
});
}
private void setupMasterVolumeOption() {
final Text masterVolumeText = get("master-volume-text");
masterVolumeText.setText(AppContext.getString("master-volume"));
final Slider masterVolumeSlider = get("master-volume-slider");
masterVolumeSlider.setMin(0);
masterVolumeSlider.setMax(100);
masterVolumeSlider.setValue(AppSettings.getSettings().getVolume());
masterVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setVolume(newValue.intValue());
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.MASTERVOLUME)).asyncPostEvent();
});
}
private void setupEffectsVolumeOption() {
final Text effectsVolumeText = get("effects-volume-text");
effectsVolumeText.setText(AppContext.getString("effects-volume"));
final Slider effectsVolumeSlider = get("effects-volume-slider");
effectsVolumeSlider.setMin(0);
effectsVolumeSlider.setMax(100);
effectsVolumeSlider.setValue(AppSettings.getSettings().getFxVolume());
effectsVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setFxVolume(newValue.intValue());
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.FX)).asyncPostEvent();
});
}
private void setupMusicVolumeOption() {
final Text musicVolumeText = get("music-volume-text");
musicVolumeText.setText(AppContext.getString("music-volume"));
final Slider musicVolumeSlider = get("music-volume-slider");
musicVolumeSlider.setMin(0);
musicVolumeSlider.setMax(100);
musicVolumeSlider.setValue(AppSettings.getSettings().getMusicVolume());
musicVolumeSlider.valueProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setMusicVolume(newValue.intValue());
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newValue.doubleValue(), VolumeControl.MUSIC)).asyncPostEvent();
});
}
private void setupThemeOption() {
final Text themeText = get("theme-text");
themeText.setText(AppContext.getString("theme"));
final ComboBox<String> themeCombobox = get("theme-combobox");
themeCombobox.getItems().addAll("dark", "light", "high-contrast");
themeCombobox.setValue(AppSettings.getSettings().getTheme());
themeCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setTheme(newValue);
App.setStyle(newValue, AppSettings.getSettings().getLayoutSize());
});
themeCombobox.setConverter(new StringConverter<>() {
@Override
public String toString(String theme) {
return AppContext.getString(theme);
}
@Override
public String fromString(String s) {
return null;
}
});
}
private void setupLayoutOption() {
final Text layoutText = get("layout-text");
layoutText.setText(AppContext.getString("layout-size"));
final ComboBox<String> layoutCombobox = get("layout-combobox");
layoutCombobox.getItems().addAll("small", "medium", "large");
layoutCombobox.setValue(AppSettings.getSettings().getLayoutSize());
layoutCombobox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
AppSettings.getSettings().setLayoutSize(newValue);
App.setStyle(AppSettings.getSettings().getTheme(), newValue);
});
layoutCombobox.setConverter(new StringConverter<>() {
@Override
public String toString(String layout) {
return AppContext.getString(layout);
}
@Override
public String fromString(String s) {
return null;
}
});
}
private void setupFullscreenOption() {
final Button fullscreenButton = get("fullscreen-button");
if (AppSettings.getSettings().getFullscreen()) {
fullscreenButton.setText(AppContext.getString("windowed"));
fullscreenButton.setOnAction(_ -> {
AppSettings.getSettings().setFullscreen(false);
App.setFullscreen(false);
});
} else {
fullscreenButton.setText(AppContext.getString("fullscreen"));
fullscreenButton.setOnAction(_ -> {
AppSettings.getSettings().setFullscreen(true);
App.setFullscreen(true);
});
}
}
}

View File

@@ -1,40 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.App;
import org.toop.app.view.View;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.text.Text;
public final class QuitView extends View {
public QuitView() {
super(false, "bg-popup");
}
@Override
public void setup() {
final Text sureHeader = header();
sureHeader.setText(AppContext.getString("are-you-sure"));
final Button yesButton = button();
yesButton.setText(AppContext.getString("yes"));
yesButton.setOnAction(_ -> { App.quit(); });
final Button noButton = button();
noButton.setText(AppContext.getString("no"));
noButton.setOnAction(_ -> { App.stopQuit(); });
add(Pos.CENTER,
fit(vbox(
sureHeader,
hbox(
yesButton,
noButton
)
))
);
}
}

View File

@@ -1,119 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.GameInformation;
import org.toop.app.Server;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Slider;
import javafx.scene.text.Text;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
public final class SendChallengeView extends View {
private final Server server;
private final String opponent;
private final BiConsumer<GameInformation.Player, String> onSend;
private final GameInformation.Player playerInformation;
public SendChallengeView(Server server, String opponent, BiConsumer<GameInformation.Player, String> onSend) {
super(false, "bg-popup");
this.server = server;
this.opponent = opponent;
this.onSend = onSend;
playerInformation = new GameInformation.Player();
}
@Override
public void setup() {
final Text challengeText = text();
challengeText.setText(AppContext.getString("challenge"));
final Text opponentHeader = header();
opponentHeader.setText(opponent);
final Text gameText = text();
gameText.setText(AppContext.getString("to-a-game-of"));
final ComboBox<String> gamesCombobox = combobox();
gamesCombobox.getItems().addAll(server.getGameList());
gamesCombobox.setValue(gamesCombobox.getItems().getFirst());
final Button sendButton = button();
sendButton.setText(AppContext.getString("send"));
sendButton.setOnAction(_ -> { onSend.accept(playerInformation, gamesCombobox.getValue()); });
final Button cancelButton = button();
cancelButton.setText(AppContext.getString("cancel"));
cancelButton.setOnAction(_ -> {
ViewStack.pop(); });
final List<Node> nodes = new ArrayList<>();
if (playerInformation.isHuman) {
final Button playerToggle = button();
playerToggle.setText(AppContext.getString("player"));
playerToggle.setOnAction(_ -> {
playerInformation.isHuman = false;
cleanup();
setup();
});
nodes.add(vbox(playerToggle));
} else {
final Button computerToggle = button();
computerToggle.setText(AppContext.getString("computer"));
computerToggle.setOnAction(_ -> {
playerInformation.isHuman = true;
cleanup();
setup();
});
nodes.add(vbox(computerToggle));
final Text computerDifficultyText = text();
computerDifficultyText.setText(AppContext.getString("computer-difficulty"));
final Slider computerDifficultySlider = slider();
computerDifficultySlider.setMin(0);
computerDifficultySlider.setMax(Server.gameToType(gamesCombobox.getValue()).getMaxDepth());
computerDifficultySlider.setValue(playerInformation.computerDifficulty);
computerDifficultySlider.valueProperty().addListener((_, _, newValue) -> {
playerInformation.computerDifficulty = newValue.intValue();
});
nodes.add(vbox(computerDifficultyText, computerDifficultySlider));
}
add(Pos.CENTER,
fit(hboxFill(
vboxFill(
challengeText,
opponentHeader,
gameText,
gamesCombobox,
separator(),
hboxFill(
sendButton,
cancelButton
)
),
vboxFill(
nodes.toArray(new Node[0])
)
))
);
}
}

View File

@@ -1,89 +0,0 @@
package org.toop.app.view.views;
import org.toop.app.view.View;
import org.toop.app.view.ViewStack;
import org.toop.app.view.displays.SongDisplay;
import org.toop.local.AppContext;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.text.Text;
import java.util.List;
import java.util.function.Consumer;
public final class ServerView extends View {
private final String user;
private final Consumer<String> onPlayerClicked;
private final Runnable onDisconnect;
private ListView<Button> listView;
public ServerView(String user, Consumer<String> onPlayerClicked, Runnable onDisconnect) {
super(true, "bg-primary");
this.user = user;
this.onPlayerClicked = onPlayerClicked;
this.onDisconnect = onDisconnect;
}
public void update(List<String> players) {
Platform.runLater(() -> {
listView.getItems().clear();
for (int i = 0; i < players.size(); i++) {
final int finalI = i;
final Button button = button();
button.setText(players.get(i));
button.setOnAction(_ -> {
onPlayerClicked.accept(players.get(finalI));
});
listView.getItems().add(button);
}
});
}
@Override
public void setup() {
final Text playerHeader = header();
playerHeader.setText(user);
listView = new ListView<Button>();
final SongDisplay songdisplay = new SongDisplay();
add(Pos.BOTTOM_RIGHT,
fit(vboxFill(
songdisplay
)));
add(Pos.CENTER,
fit(vboxFill(
vbox(
playerHeader,
separator()
),
listView
))
);
final Button disconnectButton = button();
disconnectButton.setText(AppContext.getString("disconnect"));
disconnectButton.setOnAction(_ -> {
onDisconnect.run();
ViewStack.push(new OnlineView());
});
add(Pos.BOTTOM_LEFT,
vboxFill(
disconnectButton
)
);
}
}

View File

@@ -1,8 +1,8 @@
package org.toop.app.widget.view;
import org.toop.app.GameInformation;
import org.toop.app.game.Connect4Game;
import org.toop.app.game.ReversiGame;
import org.toop.app.game.Connect4GameThread;
import org.toop.app.game.ReversiGameThread;
import org.toop.app.game.TicTacToeGameThread;
import org.toop.app.widget.Primitive;
import org.toop.app.widget.complex.PlayerInfoWidget;
@@ -33,8 +33,8 @@ public class LocalMultiplayerView extends ViewWidget {
switch (information.type) {
case TICTACTOE -> new TicTacToeGameThread(information);
case REVERSI -> new ReversiGame(information);
case CONNECT4 -> new Connect4Game(information);
case REVERSI -> new ReversiGameThread(information);
case CONNECT4 -> new Connect4GameThread(information);
// case BATTLESHIP -> new BattleshipGame(information);
}
});

View File

@@ -1,9 +1,12 @@
package org.toop.local;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.resource.ResourceManager;
import org.toop.framework.resource.resources.LocalizationAsset;
import java.util.Locale;
import java.util.MissingResourceException;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;