Compare commits
31 Commits
master
...
pyside-mig
Author | SHA1 | Date |
---|---|---|
Dorian | a2066b44d0 | |
Dorian | 4d9311ecc3 | |
Dorian | 185b226f3f | |
Dorian | 7fecb40f7d | |
Dorian | 16c715316f | |
Dorian | 750f561880 | |
Dorian | dc49718352 | |
Dorian | f9468b0562 | |
Dorian | 1079aca0bd | |
Dorian | 0df9912730 | |
Dorian | 0a8fdc0e93 | |
Dorian | 0039466767 | |
Dorian | d791840bdd | |
Dorian | cf103bcbb8 | |
Dorian | 8ec38e5020 | |
Dorian | 11f7bf2789 | |
Dorian | 6df858e7eb | |
Dorian | 02dbdaa633 | |
Dorian | d196d109ce | |
Dorian | bb21cc4577 | |
Dorian | aace9864c2 | |
Dorian | b80009850e | |
Dorian | 5d2ecec3fb | |
Dorian | c51123767c | |
Dorian | 1a23686e48 | |
Dorian | b1a0024edf | |
Dorian | 6b9ecb5785 | |
Dorian | a4e22c1f9b | |
Dorian | c3bb8b453d | |
Dorian | fff98a41df | |
Dorian | f209dc1d87 |
|
@ -1,8 +1,7 @@
|
||||||
bin
|
bin
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea
|
.idea
|
||||||
.gradle
|
|
||||||
.eclipse
|
*.pyc
|
||||||
.settings
|
docs/_build
|
||||||
*.iml
|
|
||||||
classes
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
include justcheckers/assets/*.md
|
||||||
|
include justcheckers/images/*.png
|
||||||
|
include justcheckers/images/*.jpg
|
||||||
|
include requirements.txt
|
19
README.rst
|
@ -1,26 +1,21 @@
|
||||||
======================
|
justCheckers - README
|
||||||
justCheckers - README!
|
=====================
|
||||||
======================
|
|
||||||
|
|
||||||
About the Project
|
About the Project
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
*justCheckers* is an advanced open source checkers game for Android. The aim of
|
*justCheckers* is an advanced, cross-platform, libre source checkers game. The project's aim is to make a game capable
|
||||||
the project is to make a game capable of supporting:
|
of supporting:
|
||||||
|
|
||||||
- Skinning
|
- Skinning
|
||||||
- Network Games
|
- Network Games
|
||||||
- Computer Opponents
|
- Computer Opponents
|
||||||
- Various Rules and Internationalizations
|
- Various Rules and Internationalizations
|
||||||
- Cross platform (both OS and input types)
|
- Multiple Desktop and Mobile OS
|
||||||
|
|
||||||
Current Progress
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The *justCheckers* project is in the middle of a general overhaul of the codebase to allow for a more modern approach. Both the game engine needs to get decoupled from the platform specific code.
|
|
||||||
|
|
||||||
Links
|
Links
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- Project website: http://justcheckers.org/
|
- Project website: http://justcheckers.org/
|
||||||
- Project @ Github: https://github.com/dorianpula/justcheckers
|
- Project @ Github: https://github.com/dorianpula/justcheckers
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="org.justcheckers.android"
|
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="0.1.1">
|
|
||||||
|
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name"
|
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
|
||||||
|
|
||||||
<activity android:name="org.justcheckers.android.MenuActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity android:name="org.justcheckers.android.GameActivity" />
|
|
||||||
<activity android:name="org.justcheckers.android.InfoActivity" />
|
|
||||||
<activity android:name="org.justcheckers.android.SettingsActivity" />
|
|
||||||
|
|
||||||
</application>
|
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="7" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
</manifest>
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
Modular Gradle Build for justCheckers Android
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
Gradle Android build docs:
|
|
||||||
https://sites.google.com/a/android.com/tools/tech-docs/new-build-system
|
|
||||||
*/
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
maven { url 'http://repo1.maven.org/maven2' }
|
|
||||||
|
|
||||||
}
|
|
||||||
dependencies { classpath 'com.android.tools.build:gradle:0.3' }
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'android'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers-android'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
// Androids!!!
|
|
||||||
android {
|
|
||||||
compileSdkVersion 14
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
|
||||||
java.srcDirs = ['src']
|
|
||||||
resources.srcDirs = ['src']
|
|
||||||
aild.srcDirs = ['src']
|
|
||||||
renderscript.srcDirs = ['src']
|
|
||||||
res.srcDirs = ['res']
|
|
||||||
assets.srcDirs = ['assets']
|
|
||||||
}
|
|
||||||
|
|
||||||
instrumentTest.setRoot('tests')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup build script repositories starting with Maven repositories
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url 'http://repo1.maven.org/maven2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dependency management
|
|
||||||
dependencies {
|
|
||||||
compile project(':core')
|
|
||||||
//compile 'org.slf4j:slf4j-android:1.6.1-RC1'
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
sdk.dir=/home/dorian/Coding/android-sdk-linux
|
|
|
@ -1,34 +0,0 @@
|
||||||
-optimizationpasses 5
|
|
||||||
-dontusemixedcaseclassnames
|
|
||||||
-dontskipnonpubliclibraryclasses
|
|
||||||
-dontpreverify
|
|
||||||
-verbose
|
|
||||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
|
||||||
|
|
||||||
-keep public class * extends android.app.Activity
|
|
||||||
-keep public class * extends android.app.Application
|
|
||||||
-keep public class * extends android.app.Service
|
|
||||||
-keep public class * extends android.content.BroadcastReceiver
|
|
||||||
-keep public class * extends android.content.ContentProvider
|
|
||||||
-keep public class com.android.vending.licensing.ILicensingService
|
|
||||||
|
|
||||||
-keepclasseswithmembers class * {
|
|
||||||
native <methods>;
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclasseswithmembers class * {
|
|
||||||
public <init>(android.content.Context, android.util.AttributeSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclasseswithmembers class * {
|
|
||||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclassmembers enum * {
|
|
||||||
public static **[] values();
|
|
||||||
public static ** valueOf(java.lang.String);
|
|
||||||
}
|
|
||||||
|
|
||||||
-keep class * implements android.os.Parcelable {
|
|
||||||
public static final android.os.Parcelable$Creator *;
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
# This file is automatically generated by Android Tools.
|
|
||||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
|
||||||
#
|
|
||||||
# This file must be checked in Version Control Systems.
|
|
||||||
#
|
|
||||||
# To customize properties used by the Ant build system use,
|
|
||||||
# "ant.properties", and override values to adapt the script to your
|
|
||||||
# project structure.
|
|
||||||
|
|
||||||
# Project target.
|
|
||||||
target=android-14
|
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.5 KiB |
|
@ -1,405 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/screen_root"
|
|
||||||
android:background="@drawable/backdrop"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/app_logo"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:src="@drawable/logo" />
|
|
||||||
|
|
||||||
|
|
||||||
<TableLayout android:id="@+id/game_board"
|
|
||||||
android:layout_below="@id/app_logo"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip">
|
|
||||||
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<TableLayout android:id="@+id/player_captured_pieces"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_below="@+id/app_logo"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip"
|
|
||||||
android:layout_toRightOf="@+id/game_board"
|
|
||||||
android:layout_width="wrap_content">
|
|
||||||
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:text="@string/template_opposing_player"
|
|
||||||
android:textColor="#FF000000"/>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/opposing_player_king"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/defend_king" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_king_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/opposing_player_pawn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/defend_pawn" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_pawn_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
<TableLayout android:id="@+id/opponent_captured_pieces"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_below="@id/player_captured_pieces"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip"
|
|
||||||
android:layout_toRightOf="@+id/game_board"
|
|
||||||
android:layout_width="wrap_content">
|
|
||||||
<TableRow
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/template_current_player"
|
|
||||||
android:textColor="#FF000000" android:padding="5dip"/>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/current_player_king"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/attack_king" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_king_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/current_player_pawn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/attack_pawn" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_pawn_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,407 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/screen_root"
|
|
||||||
android:background="@drawable/backdrop"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/app_logo"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:src="@drawable/logo" />
|
|
||||||
|
|
||||||
<TableLayout android:id="@+id/game_board"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip">
|
|
||||||
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/play" />
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/non_play" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<TableLayout android:id="@+id/player_captured_pieces"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_below="@+id/game_board"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip"
|
|
||||||
android:layout_width="wrap_content">
|
|
||||||
|
|
||||||
<TableRow android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:text="@string/template_opposing_player"
|
|
||||||
android:textColor="#FF000000"/>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/opposing_player_king"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/defend_king" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_king_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/opposing_player_pawn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/defend_pawn" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/opposing_player_pawn_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
<TableLayout android:id="@+id/opponent_captured_pieces"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_below="@id/player_captured_pieces"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip"
|
|
||||||
android:layout_width="wrap_content">
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/template_current_player"
|
|
||||||
android:textColor="#FF000000" android:padding="5dip"/>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/current_player_king"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/attack_king" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_king_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/current_player_pawn"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/attack_pawn" />
|
|
||||||
|
|
||||||
<TextView android:id="@+id/current_player_pawn_captured"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#FF000000"
|
|
||||||
android:text="@string/template_capture_amounts" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/screen_root"
|
|
||||||
android:background="@drawable/backdrop"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/app_logo"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:src="@drawable/logo" />
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_below="@+id/app_logo"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dip"
|
|
||||||
android:layout_width="fill_parent">
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/info_text"
|
|
||||||
android:background="#BBFFFFFF"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:textColor="#FF000000" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,70 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/screen_root"
|
|
||||||
android:background="@drawable/backdrop"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/app_logo"
|
|
||||||
android:background="#DDFFFFFF"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:src="@drawable/logo"/>
|
|
||||||
|
|
||||||
<TableLayout android:id="@+id/menu_table"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dp">
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<Button android:id="@+id/game_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_play_checkers" />
|
|
||||||
<Button android:id="@+id/website_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_visit_us" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
|
|
||||||
<Button android:id="@+id/about_us_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_about_us" />
|
|
||||||
<Button android:id="@+id/license_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_license" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
<TableRow
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<Button android:id="@+id/settings_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_settings" />
|
|
||||||
<Button android:id="@+id/quit_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/caption_quit" />
|
|
||||||
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<PreferenceCategory
|
|
||||||
android:title="Application Settings">
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
android:title="Start New Game on Startup"
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:summary="Should the app automatically start a new game."
|
|
||||||
android:key="startGameAtStartup" />
|
|
||||||
|
|
||||||
<!-- CheckBoxPreference
|
|
||||||
android:title="Save Game on Exit"
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:summary="Saves the game automatically when exiting the app."
|
|
||||||
android:key="saveGameAtExit" /-->
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
<!-- PreferenceCategory
|
|
||||||
android:title="Game Settings">
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
android:title="Ask What Variant to Play"
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:summary="Asks what variant of checkers you want to play, for each new game."
|
|
||||||
android:key="askVariantToPlay" />
|
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
android:title="Type of Checkers Game"
|
|
||||||
android:summary="Should the app automatically start a new game."
|
|
||||||
android:defaultValue="American/Standard"
|
|
||||||
android:entries="@array/checkers_variants"
|
|
||||||
android:entryValues="@array/checkers_variants"
|
|
||||||
android:key="checkersVariant" />
|
|
||||||
|
|
||||||
</PreferenceCategory -->
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
|
|
@ -1,42 +0,0 @@
|
||||||
== What is justCheckers? ==
|
|
||||||
justCheckers is an open source advanced checkers game built using Java. The aim
|
|
||||||
of the project is to create a checkers game that:
|
|
||||||
|
|
||||||
* handles skins and themes
|
|
||||||
* handles multimedia
|
|
||||||
* allows for network games
|
|
||||||
* contains a powerful yet fun computer opponent
|
|
||||||
* simplifies managing on-line checkers tournaments
|
|
||||||
* handles different checker rules
|
|
||||||
|
|
||||||
Project homepage: http://justcheckers.sourceforge.net/
|
|
||||||
|
|
||||||
== Current Developers ==
|
|
||||||
* Dorian Pula
|
|
||||||
** Founder, lead developer, project management, documentation & core programming.
|
|
||||||
|
|
||||||
== Past Developers ==
|
|
||||||
* Chris Bellini
|
|
||||||
** Game engine data objects, XML settings & project management.
|
|
||||||
** Versions 0.0-0.1
|
|
||||||
|
|
||||||
* Daniel D'Alimonte (skwirl)
|
|
||||||
** Code clean-up, refactoring, documentation & file releases.
|
|
||||||
** Versions 0.0-0.1
|
|
||||||
|
|
||||||
* Ross Etchells
|
|
||||||
** Game engine logic and progressing.
|
|
||||||
** Versions 0.0-0.1
|
|
||||||
|
|
||||||
* Rras Lekone
|
|
||||||
** Console UI (jCurses)
|
|
||||||
** Versions 0.0
|
|
||||||
|
|
||||||
* Brinick Simmons
|
|
||||||
** Core programming, XML settings and processing.
|
|
||||||
** Versions 0.0-0.1
|
|
||||||
|
|
||||||
== Inspiration ==
|
|
||||||
* Nick Nolfi
|
|
||||||
** Creator of the Chubby Checkers project and assignment.
|
|
||||||
** Inspiration for Civilization Checkers and justCheckers.
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">justCheckers</string>
|
|
||||||
<string name="app_version">0.2-alpha</string>
|
|
||||||
<string name="project_website">http://justcheckers.org/</string>
|
|
||||||
<string-array name="checkers_variants">
|
|
||||||
<item>American/Standard</item>
|
|
||||||
<item>European</item>
|
|
||||||
<item>Canadian</item>
|
|
||||||
</string-array>
|
|
||||||
</resources>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="caption_about_us">About Us</string>
|
|
||||||
<string name="caption_license">License</string>
|
|
||||||
<string name="caption_play_checkers">Play Checkers</string>
|
|
||||||
<string name="caption_settings">Settings</string>
|
|
||||||
<string name="caption_visit_us">Visit Our Website</string>
|
|
||||||
<string name="caption_quit">Quit</string>
|
|
||||||
</resources>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="template_capture_amounts">x0</string>
|
|
||||||
<string name="template_current_player">Current Player</string>
|
|
||||||
<string name="template_opposing_player">Opposing Player</string>
|
|
||||||
</resources>
|
|
|
@ -1,81 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GameActivity.java - The activity that handles the actual checkers games.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.android;
|
|
||||||
|
|
||||||
import org.justcheckers.game.Game;
|
|
||||||
import org.justcheckers.game.Rulebook;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
|
|
||||||
public class GameActivity extends Activity implements OnClickListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Setup the user interface for the main menu.
|
|
||||||
|
|
||||||
// Weirdness in orientation values in Galaxy Tab.
|
|
||||||
// http://www.ceveni.com/2009/08/how-to-get-screen-orientation-in.html
|
|
||||||
int screenOrientation =
|
|
||||||
this.getWindowManager().getDefaultDisplay().getOrientation();
|
|
||||||
|
|
||||||
//TODO: Cleaner per device implementation. Developed on Samsung Galaxy S Vibrant.
|
|
||||||
if (screenOrientation == 1) {
|
|
||||||
// Counter-clockwise landscape
|
|
||||||
this.setContentView(R.layout.game_screen_landscape);
|
|
||||||
} else if (screenOrientation == 3) {
|
|
||||||
// Clockwise landscape
|
|
||||||
this.setContentView(R.layout.game_screen_landscape);
|
|
||||||
} else if (screenOrientation == 0) {
|
|
||||||
// Portrait for Samsung Galaxy devices.
|
|
||||||
this.setContentView(R.layout.game_screen_portrait);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View view) {
|
|
||||||
//TODO: Stub
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a new game with the specified rulebook.
|
|
||||||
*
|
|
||||||
* @param rules
|
|
||||||
* The rules for the new game.
|
|
||||||
*/
|
|
||||||
public static void startGame(Rulebook rules) {
|
|
||||||
Game currentGame = new Game(rules.getCheckersVariant());
|
|
||||||
/* Instead of specialized UI commands, just a single method
|
|
||||||
that updates the UI with the current state of the game. */
|
|
||||||
// ui.setCurrentGame(currentGame);
|
|
||||||
//
|
|
||||||
// // Current until different game types are added.
|
|
||||||
// ui.clearBoard();
|
|
||||||
// ui.placePieces();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
InfoActivity.java - The activity that provides built-in information.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.android;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import org.justcheckers.common.GlobalConstants;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
public class InfoActivity extends Activity {
|
|
||||||
|
|
||||||
private int flagInformationToDisplay;
|
|
||||||
|
|
||||||
//TODO: Clean this up into something more modularized.
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Setup the user interface for the main menu.
|
|
||||||
this.setContentView(R.layout.info_screen);
|
|
||||||
|
|
||||||
// Figure out which text to load. The default
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
this.flagInformationToDisplay =
|
|
||||||
savedInstanceState.getInt(GlobalConstants.EXTRA_INFORMATION_DISPLAY_FLAG);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Bundle extras = this.getIntent().getExtras();
|
|
||||||
if (extras != null) {
|
|
||||||
this.flagInformationToDisplay =
|
|
||||||
extras.getInt(GlobalConstants.EXTRA_INFORMATION_DISPLAY_FLAG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the right text.
|
|
||||||
int rawInfoRes = 0;
|
|
||||||
if (this.flagInformationToDisplay == GlobalConstants.FLAG_INFORMATION_DISPLAY_ABOUT_US) {
|
|
||||||
rawInfoRes = R.raw.readme;
|
|
||||||
} else if (this.flagInformationToDisplay == GlobalConstants.FLAG_INFORMATION_DISPLAY_LICENSE) {
|
|
||||||
rawInfoRes = R.raw.gpl_3_license;
|
|
||||||
} else {
|
|
||||||
rawInfoRes = R.raw.readme;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the raw document into a string.
|
|
||||||
InputStream docInfoStream = this.getResources().openRawResource(rawInfoRes);
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(docInfoStream));
|
|
||||||
String result = "Text here";
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Gather all the data.
|
|
||||||
StringBuilder buildDoc = new StringBuilder();
|
|
||||||
String docLine = reader.readLine();
|
|
||||||
|
|
||||||
while (docLine != null) {
|
|
||||||
buildDoc.append(docLine + "\n");
|
|
||||||
docLine = reader.readLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = buildDoc.toString();
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("InfoActivity", "Input error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView infoText = (TextView) this.findViewById(R.id.info_text);
|
|
||||||
infoText.setText(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putInt(GlobalConstants.EXTRA_INFORMATION_DISPLAY_FLAG,
|
|
||||||
this.flagInformationToDisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
MenuActivity.java - The activity that provides the main menu for the app.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.android;
|
|
||||||
|
|
||||||
import org.justcheckers.common.GlobalConstants;
|
|
||||||
import org.justcheckers.common.LoggingAndStatistics;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
public class MenuActivity extends Activity implements OnClickListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Setup the user interface for the main menu.
|
|
||||||
this.setContentView(R.layout.main_menu);
|
|
||||||
|
|
||||||
// Link up all the UI elements with their listeners.
|
|
||||||
Button menuButton = (Button) this.findViewById(R.id.game_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.game_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.website_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.settings_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.about_us_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.license_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
menuButton = (Button) this.findViewById(R.id.quit_button);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
|
|
||||||
// TODO: Move logging info in a better place.
|
|
||||||
// LoggingAndStatistics.logApplicationInfo(this);
|
|
||||||
LoggingAndStatistics.logDeviceAndSystemInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View view) {
|
|
||||||
// Determine which view fired off this event.
|
|
||||||
switch (view.getId()) {
|
|
||||||
case R.id.game_button:
|
|
||||||
this.startGame();
|
|
||||||
break;
|
|
||||||
case R.id.website_button:
|
|
||||||
this.launchWebsite();
|
|
||||||
break;
|
|
||||||
case R.id.settings_button:
|
|
||||||
this.displaySettings();
|
|
||||||
break;
|
|
||||||
case R.id.about_us_button:
|
|
||||||
this.displayInfo(GlobalConstants.FLAG_INFORMATION_DISPLAY_ABOUT_US);
|
|
||||||
break;
|
|
||||||
case R.id.license_button:
|
|
||||||
this.displayInfo(GlobalConstants.FLAG_INFORMATION_DISPLAY_LICENSE);
|
|
||||||
break;
|
|
||||||
case R.id.quit_button:
|
|
||||||
this.quitApp();
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quits the application.
|
|
||||||
*/
|
|
||||||
private void quitApp() {
|
|
||||||
this.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays an information screen.
|
|
||||||
*/
|
|
||||||
private void displayInfo(int infoToDisplay) {
|
|
||||||
|
|
||||||
// Validate info.
|
|
||||||
if ((infoToDisplay != GlobalConstants.FLAG_INFORMATION_DISPLAY_ABOUT_US) &&
|
|
||||||
(infoToDisplay != GlobalConstants.FLAG_INFORMATION_DISPLAY_LICENSE)) {
|
|
||||||
infoToDisplay = GlobalConstants.FLAG_INFORMATION_DISPLAY_ABOUT_US;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Intent launchDisplay = new Intent(this, InfoActivity.class);
|
|
||||||
launchDisplay.putExtra(GlobalConstants.EXTRA_INFORMATION_DISPLAY_FLAG,
|
|
||||||
infoToDisplay);
|
|
||||||
startActivity(launchDisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the settings for the application.
|
|
||||||
*/
|
|
||||||
private void displaySettings() {
|
|
||||||
Intent launchDisplay = new Intent(this, SettingsActivity.class);
|
|
||||||
startActivity(launchDisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an external browser to visit the project's website.
|
|
||||||
*/
|
|
||||||
private void launchWebsite() {
|
|
||||||
String url = this.getString(R.string.project_website);
|
|
||||||
Intent launcher = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
|
||||||
startActivity(launcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a new game or continues an existing one.
|
|
||||||
*/
|
|
||||||
private void startGame() {
|
|
||||||
Intent launchDisplay = new Intent(this, GameActivity.class);
|
|
||||||
startActivity(launchDisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
SettingsActivity.java - The activity for adjustings settings in the app.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.android;
|
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceActivity;
|
|
||||||
|
|
||||||
public class SettingsActivity extends PreferenceActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
this.addPreferencesFromResource(R.layout.settings_screen);
|
|
||||||
this.getListView().setBackgroundResource(R.drawable.backdrop);
|
|
||||||
this.getListView().setCacheColorHint(Color.TRANSPARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
23
build.gradle
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
Modular Gradle Build for justCheckers
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
Gradle Android build docs:
|
|
||||||
https://sites.google.com/a/android.com/tools/tech-docs/new-build-system
|
|
||||||
*/
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
// TODO Add in extra targets for project setup or a simplified Gradle build API.
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
Gradle Build for justCheckers - Console
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers-console'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
// TODO Add in build for the terminal client.
|
|
||||||
// TODO Base of justcheckers-core
|
|
||||||
|
|
||||||
// TODO Look into potential terminal libraries...
|
|
||||||
/*
|
|
||||||
Ideas: http://stackoverflow.com/questions/1321308/whats-the-best-way-to-get-text-user-interfaces-ncurses-like-functionality-in
|
|
||||||
- Laterna: https://code.google.com/p/lanterna/
|
|
||||||
- jCurses: http://sourceforge.net/projects/javacurses/
|
|
||||||
- TUIAWT: http://bmsi.com/tuipeer/
|
|
||||||
- CHARVA: http://www.pitman.co.za/projects/charva/index.html
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
Gradle Build for justCheckers - Core
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers-core'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
project.ext {
|
|
||||||
appName = 'justcheckers-core'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup build script repositories starting with Maven repositories
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url 'http://repo1.maven.org/maven2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dependency management
|
|
||||||
dependencies {
|
|
||||||
compile 'jdom:jdom:0.7'
|
|
||||||
compile 'org.slf4j:slf4j-api:1.7.5'
|
|
||||||
testCompile 'org.testng:testng:6.8'
|
|
||||||
}
|
|
||||||
|
|
||||||
// At the end of day we just need a JAR and a WAR.
|
|
||||||
ext.sharedManifest = manifest {
|
|
||||||
|
|
||||||
attributes(
|
|
||||||
'App-Name' : project.appName,
|
|
||||||
'App-Version' : version,
|
|
||||||
'Build-User' : System.properties['user.name'],
|
|
||||||
'Build-Time' : new Date().format('yyyy-MMMM-dd HH:mm:ss'),
|
|
||||||
'Build-OS' : System.properties['os.name'] + ' - version ' + System.properties['os.version'],
|
|
||||||
'Build-Sys' : System.properties['os.arch'],
|
|
||||||
'Java-Version' : System.properties['java.version'],
|
|
||||||
'Java-Vendor' : System.properties['java.vendor'],
|
|
||||||
'Java-VM' :
|
|
||||||
System.properties['java.vm.vendor'] + ' ' + System.properties['java.vm.name'] + ' v'
|
|
||||||
+ System.properties['java.vm.version'])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the JAR.
|
|
||||||
jar {
|
|
||||||
enabled = true
|
|
||||||
includeEmptyDirs = false
|
|
||||||
manifest = sharedManifest
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GlobalConstants.java - Constants for the entire application.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.common;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Organizational class to keep all the constants in.
|
|
||||||
* @author Dorian Pula
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GlobalConstants {
|
|
||||||
|
|
||||||
/** Flag for the information screen to display a "About Us". */
|
|
||||||
public final static int FLAG_INFORMATION_DISPLAY_ABOUT_US = 0;
|
|
||||||
/** Flag for the information screen to display the license of the app. */
|
|
||||||
public final static int FLAG_INFORMATION_DISPLAY_LICENSE = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The extras key that contains the information screens needs to display
|
|
||||||
* the right information.
|
|
||||||
*/
|
|
||||||
public final static String EXTRA_INFORMATION_DISPLAY_FLAG = "info-display";
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GameLoop.java - Main controlling class for the justCheckers game.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.common;
|
|
||||||
|
|
||||||
// TODO Resolve this with separation of various platform setups...
|
|
||||||
//import org.justcheckers.android.R;
|
|
||||||
//
|
|
||||||
//import android.app.Activity;
|
|
||||||
//import android.os.Build;
|
|
||||||
//import android.util.Log;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions for logging errors and gathering statistics.
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
*/
|
|
||||||
public abstract class LoggingAndStatistics {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs information about the program. Displays the game's header and
|
|
||||||
* relevant system properties at runtime.
|
|
||||||
*/
|
|
||||||
public static void logApplicationInfo(String gameVersion, String gameWebsite) {
|
|
||||||
|
|
||||||
// TODO Fix
|
|
||||||
// String gameVersion = caller.getString(R.string.app_version);
|
|
||||||
// String gameWebsite = caller.getString(R.string.project_website);
|
|
||||||
String appInfo = "justCheckers -- Version:" + gameVersion
|
|
||||||
+ " - Website: " + gameWebsite;
|
|
||||||
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(LoggingAndStatistics.class);
|
|
||||||
log.info("ApplInfo", appInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs information about the device and system, the app is
|
|
||||||
* running on.
|
|
||||||
*/
|
|
||||||
public static void logDeviceAndSystemInfo() {
|
|
||||||
|
|
||||||
// System properties.
|
|
||||||
// String sysList = "SDK version: " + Build.VERSION.RELEASE
|
|
||||||
// + " - API: " + Build.VERSION.SDK_INT
|
|
||||||
// + " - Device: " + Build.MANUFACTURER + " " + Build.MODEL;
|
|
||||||
// TODO Fix
|
|
||||||
String sysList = "FIXME";
|
|
||||||
|
|
||||||
Logger log = LoggerFactory.getLogger(LoggingAndStatistics.class);
|
|
||||||
log.info("DevSysInfo", sysList);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,497 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
Board.java -- Container for the state of the board of a game.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Container for the state of the checker board during a game.
|
|
||||||
*
|
|
||||||
* The size of the board is defined by the number of squares along one side,
|
|
||||||
* since all checker boards are square. The board coordinate system has both
|
|
||||||
* horizontal and vertical numeric components ranging from 0 to boardSize-1.
|
|
||||||
* Depicted on-screen, the horizontal component extends to the right and the
|
|
||||||
* vertical component extends downwards, making the upper left square (0, 0) and
|
|
||||||
* the lower right square (boardSize-1, boardSize-1).
|
|
||||||
*
|
|
||||||
* <b>Navigating through the Board</b> Internally, the checker board is
|
|
||||||
* organized as a two-dimensional array. So when iterating through the board,
|
|
||||||
* you first specify the vertical component and then the horizontal component.
|
|
||||||
* Another way of thinking about is first specifying which row you want to look
|
|
||||||
* at from top to bottom. Then you specify how across the row you are looking at
|
|
||||||
* from left to right.
|
|
||||||
*
|
|
||||||
* <b>Players Places</b> The light player (the starting player) starts at the
|
|
||||||
* top of the board. The dark player starts at the bottom of the board.
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
* @author Ross Etchells
|
|
||||||
*/
|
|
||||||
public class Board {
|
|
||||||
|
|
||||||
/** Constant representing a dark king. */
|
|
||||||
public static final int DARK_KING = 4;
|
|
||||||
/** Constant representing a dark single man. */
|
|
||||||
public static final int DARK_PAWN = 3;
|
|
||||||
/** Constant representing an empty space. */
|
|
||||||
public static final int EMPTY_SPACE = 0;
|
|
||||||
// -- Constants ------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Constant representing an illegal square. That is a white square in
|
|
||||||
* checkers.
|
|
||||||
*/
|
|
||||||
public static final int ILLEGAL_SPACE = -1;
|
|
||||||
/** Constant representing a light king. */
|
|
||||||
public static final int LIGHT_KING = 2;
|
|
||||||
/** Constant representing a light single man. */
|
|
||||||
public static final int LIGHT_PAWN = 1;
|
|
||||||
|
|
||||||
// -- Object Fields --------------------------------------------------------
|
|
||||||
|
|
||||||
/** Is the board mirrored or a regular checker board. */
|
|
||||||
private final boolean amIMirrored;
|
|
||||||
/**
|
|
||||||
* Holds the positions of the pieces on the board.
|
|
||||||
*/
|
|
||||||
private final int[][] board;
|
|
||||||
/** The size of the board. */
|
|
||||||
private final int boardSize;
|
|
||||||
/** A reference to the rules being used. */
|
|
||||||
private final Rulebook myRules;
|
|
||||||
|
|
||||||
// -- Constructors ---------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Creates a new board for checkers.
|
|
||||||
*
|
|
||||||
* @param rules
|
|
||||||
* The rules for this board.
|
|
||||||
*/
|
|
||||||
public Board(Rulebook rules) {
|
|
||||||
this.myRules = rules;
|
|
||||||
final int size = this.myRules.getBoardSize();
|
|
||||||
this.board = new int[size][size];
|
|
||||||
this.boardSize = size;
|
|
||||||
this.amIMirrored = this.myRules.isBoardMirrored();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Public Methods (Setting Up the Board) --------------------------------
|
|
||||||
/**
|
|
||||||
* Clears the board of pieces. Creates a brand new empty board already laid
|
|
||||||
* out by the rules (regular or mirrored).
|
|
||||||
*/
|
|
||||||
public void clearBoard() {
|
|
||||||
for (int row = 0; this.boardSize > row; row++) {
|
|
||||||
for (int col = 0; this.boardSize > col; col++) {
|
|
||||||
|
|
||||||
// Mirrored has opposite setup to a regular board.
|
|
||||||
if (row % 2 == 0 && col % 2 == 0) {
|
|
||||||
if (this.amIMirrored) {
|
|
||||||
this.board[row][col] = Board.ILLEGAL_SPACE;
|
|
||||||
} else {
|
|
||||||
this.board[row][col] = Board.EMPTY_SPACE;
|
|
||||||
}
|
|
||||||
} else if (row % 2 == 0 && col % 2 == 1) {
|
|
||||||
if (this.amIMirrored) {
|
|
||||||
this.board[row][col] = Board.EMPTY_SPACE;
|
|
||||||
} else {
|
|
||||||
this.board[row][col] = Board.ILLEGAL_SPACE;
|
|
||||||
}
|
|
||||||
} else if (row % 2 == 1 && col % 2 == 0) {
|
|
||||||
if (this.amIMirrored) {
|
|
||||||
this.board[row][col] = Board.EMPTY_SPACE;
|
|
||||||
} else {
|
|
||||||
this.board[row][col] = Board.ILLEGAL_SPACE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.amIMirrored) {
|
|
||||||
this.board[row][col] = Board.ILLEGAL_SPACE;
|
|
||||||
} else {
|
|
||||||
this.board[row][col] = Board.EMPTY_SPACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Get/Set Methods ------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Gets the size of the board. The board size is measured as the number of
|
|
||||||
* squares down one side of the board.
|
|
||||||
*
|
|
||||||
* @return The size of the board.
|
|
||||||
*/
|
|
||||||
public int getBoardSize() {
|
|
||||||
return this.boardSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a reference to a 2 dimensional array representation of the
|
|
||||||
* current board state. This is for use by the user interface. Each
|
|
||||||
* dimension of the array extends from 0 to boardSize - 1. Note that the
|
|
||||||
* referenced array is a clone of the internal board representation. Changes
|
|
||||||
* made to the array will not affect the board state.
|
|
||||||
*
|
|
||||||
* @return A 2 dimensional array representing the current state of the
|
|
||||||
* board.
|
|
||||||
*/
|
|
||||||
public int[][] getBoardState() {
|
|
||||||
final int[][] repBoard = new int[this.boardSize][this.boardSize];
|
|
||||||
System.arraycopy(this.board, 0, repBoard, 0, this.boardSize);
|
|
||||||
return repBoard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the piece at board coordinate (row, col) is dark. If
|
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the piece at the specified coordinate is dark. False if
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isDark(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.DARK_KING
|
|
||||||
|| this.board[row][col] == Board.DARK_PAWN;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the piece at board coordinate (row, col) is empty. If
|
|
||||||
* the coordinates do not exist on the board or is illegal, this method will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the piece at the specified coordinate is empty. False if
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isEmpty(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.EMPTY_SPACE;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the board coordinate (x, y) is used in the game. In
|
|
||||||
* most cases, all light spaces on the board will be considered illegal.
|
|
||||||
* Also, any coordinate which does not exist is also considered illegal.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the specified coordinate is nonexistent or unused in the
|
|
||||||
* current rules. False if otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isIllegalSpace(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.ILLEGAL_SPACE;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the piece at board coordinate (row, col) is a king. If
|
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the piece at the specified coordinate is a king. False if
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isKing(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.LIGHT_KING
|
|
||||||
|| this.board[row][col] == Board.DARK_KING;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if a position specified is legal. Returns true if the position is
|
|
||||||
* on the board, and if the space is not an illegal white space. Returns
|
|
||||||
* false otherwise.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row coordinate of the position.
|
|
||||||
* @param col
|
|
||||||
* The column coordinate of the position.
|
|
||||||
* @return Returns true if the position is a legal playing position.
|
|
||||||
*/
|
|
||||||
public boolean isLegalPosition(int row, int col) {
|
|
||||||
return row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize && !this.isIllegalSpace(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the piece at board coordinate (row, col) is light. If
|
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the piece at the specified coordinate is light. False if
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isLight(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.LIGHT_KING
|
|
||||||
|| this.board[row][col] == Board.LIGHT_PAWN;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the piece at board coordinate (row, col) is a pawn. If
|
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row of the square.
|
|
||||||
* @param col
|
|
||||||
* The column of the square.
|
|
||||||
* @return True if the piece at the specified coordinate is a pawn. False if
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isPawn(int row, int col) {
|
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
|
||||||
&& col < this.boardSize) {
|
|
||||||
return this.board[row][col] == Board.LIGHT_PAWN
|
|
||||||
|| this.board[row][col] == Board.DARK_PAWN;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Board Updating Methods -----------------------------------------------
|
|
||||||
/**
|
|
||||||
* Moves a pieces from one location to another. This method should be called
|
|
||||||
* from the Game using this Board. This method does not check for rule
|
|
||||||
* validity but does check for illegal white spaces. Also checks that the
|
|
||||||
* destination position is empty.
|
|
||||||
*
|
|
||||||
* @param sourceRow
|
|
||||||
* The row from where the piece is moving from.
|
|
||||||
* @param sourceCol
|
|
||||||
* The column from where the piece is moving from.
|
|
||||||
* @param targetRow
|
|
||||||
* The row to where the piece is moving to.
|
|
||||||
* @param targetCol
|
|
||||||
* The column to where the piece is moving to.
|
|
||||||
*/
|
|
||||||
protected void movePiece(int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
if (this.isLegalPosition(sourceRow, sourceCol)
|
|
||||||
&& this.isLegalPosition(targetRow, targetCol)
|
|
||||||
&& this.board[targetRow][targetCol] == Board.EMPTY_SPACE) {
|
|
||||||
|
|
||||||
final int piece = this.board[sourceRow][sourceCol];
|
|
||||||
this.board[targetRow][targetCol] = piece;
|
|
||||||
this.board[sourceRow][sourceCol] = Board.EMPTY_SPACE;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a pieces from the specified location. This method should be
|
|
||||||
* called from the Game using this Board. This method does not check for
|
|
||||||
* rule validity but does check for illegal white spaces.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row where the piece is to be removed from.
|
|
||||||
* @param col
|
|
||||||
* The column where the piece is to be removed from.
|
|
||||||
*/
|
|
||||||
protected void removePiece(int row, int col) {
|
|
||||||
|
|
||||||
if (this.isLegalPosition(row, col)) {
|
|
||||||
this.board[row][col] = Board.EMPTY_SPACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setups the board for a new game. There are three different setups for the
|
|
||||||
* three different types of boards:
|
|
||||||
*
|
|
||||||
* <table>
|
|
||||||
* <tr>
|
|
||||||
* <b>
|
|
||||||
* <td>Name</td>
|
|
||||||
* <td>Size</td>
|
|
||||||
* <td>Number of Pieces Per Player</td>
|
|
||||||
* <td>Number of Rows Per Player</td>
|
|
||||||
* </b>
|
|
||||||
* </tr>
|
|
||||||
* <tr>
|
|
||||||
* <td>Standard</td>
|
|
||||||
* <td>8 x 8</td>
|
|
||||||
* <td>12</td>
|
|
||||||
* <td>3</td>
|
|
||||||
* </tr>
|
|
||||||
* <tr>
|
|
||||||
* <td>International</td>
|
|
||||||
* <td>10 x 10</td>
|
|
||||||
* <td>20</td>
|
|
||||||
* <td>4</td>
|
|
||||||
* </tr>
|
|
||||||
* <tr>
|
|
||||||
* <td>Canadian</td>
|
|
||||||
* <td>12 x 12</td>
|
|
||||||
* <td>30</td>
|
|
||||||
* <td>5</td>
|
|
||||||
* </tr>
|
|
||||||
* </table>
|
|
||||||
*
|
|
||||||
* The columns containing the players' tokens alternate between columns. The
|
|
||||||
* dark player traditionally takes the first few upper rows (0-3). The light
|
|
||||||
* player takes the last of the lower rows (5-7, 6-9 or 7-11).
|
|
||||||
*
|
|
||||||
* Note that the suicide checkers variant has a completely different setup,
|
|
||||||
* and has a setup function of its own: setupNewSuicideGame().
|
|
||||||
*/
|
|
||||||
public void setupNewGame() {
|
|
||||||
this.clearBoard();
|
|
||||||
|
|
||||||
if (this.myRules.getCheckersVariant() == Rulebook.SUICIDE_CHECKERS) {
|
|
||||||
this.setupNewSuicideGame();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Used to decide which rows to fill up.
|
|
||||||
int darkPlayerBottomRow;
|
|
||||||
int lightPlayerTopRow;
|
|
||||||
|
|
||||||
// Figure out the size of the board.
|
|
||||||
if (this.boardSize == Rulebook.INTERNATIONAL_BOARD_SIZE) {
|
|
||||||
darkPlayerBottomRow = 3;
|
|
||||||
lightPlayerTopRow = 6;
|
|
||||||
} else if (this.boardSize == Rulebook.CANADIAN_BOARD_SIZE) {
|
|
||||||
darkPlayerBottomRow = 3;
|
|
||||||
lightPlayerTopRow = 7;
|
|
||||||
} else { // Default board is 8x8 Standard size.
|
|
||||||
darkPlayerBottomRow = 2;
|
|
||||||
lightPlayerTopRow = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through the board and set it up.
|
|
||||||
for (int row = 0; row < this.boardSize; row++) {
|
|
||||||
for (int col = 0; col < this.boardSize; col++) {
|
|
||||||
if (row <= darkPlayerBottomRow
|
|
||||||
&& this.board[row][col] == Board.EMPTY_SPACE) {
|
|
||||||
this.board[row][col] = Board.DARK_PAWN;
|
|
||||||
} else if (row >= lightPlayerTopRow
|
|
||||||
&& this.board[row][col] == Board.EMPTY_SPACE) {
|
|
||||||
this.board[row][col] = Board.LIGHT_PAWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setups a checker board according to the suicide "French" rules.
|
|
||||||
*/
|
|
||||||
private void setupNewSuicideGame() {
|
|
||||||
// TODO: Implement the suicide game setup.
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Private (Implementation) Methods -------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string to represent the board state. This string is formatted
|
|
||||||
* for use as a simple board display in the command window.
|
|
||||||
*
|
|
||||||
* <b>Legend</b> ## - White space which the piece can not move on to. __ -
|
|
||||||
* An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn.
|
|
||||||
* DK - A dark king.
|
|
||||||
*
|
|
||||||
* @return A string representing the current board state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
// Prepare for output with a nice looking to banner.
|
|
||||||
String output = " ";
|
|
||||||
for (int i = 0; i < this.boardSize; i++) {
|
|
||||||
if (i < 9) {
|
|
||||||
output = output + " " + (i + 1);
|
|
||||||
} else {
|
|
||||||
output = output + " " + (i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output = output + "\n\n";
|
|
||||||
|
|
||||||
// Go row by row, printing out the row number and the board's state.
|
|
||||||
for (int row = 0; row < this.boardSize; row++) {
|
|
||||||
if (row < 9) {
|
|
||||||
output = output + " " + (row + 1);
|
|
||||||
} else {
|
|
||||||
output = output + " " + (row + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current row's state.
|
|
||||||
for (int col = 0; col < this.boardSize; col++) {
|
|
||||||
switch (this.board[row][col]) {
|
|
||||||
case Board.ILLEGAL_SPACE:
|
|
||||||
output = output + "## ";
|
|
||||||
break;
|
|
||||||
case Board.EMPTY_SPACE:
|
|
||||||
output = output + "__ ";
|
|
||||||
break;
|
|
||||||
case Board.LIGHT_PAWN:
|
|
||||||
output = output + "LP ";
|
|
||||||
break;
|
|
||||||
case Board.LIGHT_KING:
|
|
||||||
output = output + "LK ";
|
|
||||||
break;
|
|
||||||
case Board.DARK_PAWN:
|
|
||||||
output = output + "DP ";
|
|
||||||
break;
|
|
||||||
case Board.DARK_KING:
|
|
||||||
output = output + "DK ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output = output + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,249 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
Board.java -- Container for the state of a game in progress.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main game handling object of GameLoop.
|
|
||||||
*
|
|
||||||
* Objects registering as observers on an instance of GameEngine will be
|
|
||||||
* notified of a change in either the board state or the turn state. The turn
|
|
||||||
* will change automatically when a complete move is made. Multiple jumps are
|
|
||||||
* managed by a call to the makeMove method for each jump segment, and the turn
|
|
||||||
* will not pass to the other player until the jump sequence is complete.
|
|
||||||
*
|
|
||||||
* @author Ross Etchells
|
|
||||||
* @author Dorian Pula
|
|
||||||
*/
|
|
||||||
public class Game {
|
|
||||||
|
|
||||||
// -- Constants -----------------------------------------------------------
|
|
||||||
/** State of the game when the dark player wins. */
|
|
||||||
public static final int STATE_DARK_VICTORY = 2;
|
|
||||||
/** State of the game when both players draw. */
|
|
||||||
public static final int STATE_GAME_DRAWN = 3;
|
|
||||||
/** State of the game when game is in progress. */
|
|
||||||
public static final int STATE_GAME_IN_PROGRESS = 0;
|
|
||||||
/** State of the game when the light player wins. */
|
|
||||||
public static final int STATE_LIGHT_VICTORY = 1;
|
|
||||||
|
|
||||||
// -- Object Fields -------------------------------------------------------
|
|
||||||
/** Represents the dark (usually defending) player. */
|
|
||||||
private Player darkPlayer;
|
|
||||||
/** Contains the current checker board used for the game. */
|
|
||||||
private Board gameBoard;
|
|
||||||
/** Contains the current rules used for playing the game. */
|
|
||||||
private Rulebook gameRules;
|
|
||||||
/** The state of the game. */
|
|
||||||
private int gameState;
|
|
||||||
/**
|
|
||||||
* This point holds the coordinates of a piece making a jump. Mostly used
|
|
||||||
* for a piece whose move has not finished after 1 jump. This point is set
|
|
||||||
* to null if not in use.
|
|
||||||
*/
|
|
||||||
private final IPoint jumpInProgress;
|
|
||||||
/** Represents the light (usually attacking) player. */
|
|
||||||
private Player lightPlayer;
|
|
||||||
/** Represents whose turn it is. */
|
|
||||||
private boolean lightPlayerTurn;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Game needs to declare who won or better yet, the state of the game
|
|
||||||
* to be: in progress, light win, dark win or draw.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -- Constructors --------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Create a new game. Uses the defaults of two unnamed players and the
|
|
||||||
* American rules.
|
|
||||||
*/
|
|
||||||
public Game() {
|
|
||||||
this(Rulebook.AMERICAN_CHECKERS, new Player(), new Player());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new game. Uses the default of two unnamed players. The variant
|
|
||||||
* (which rules) can be set here.
|
|
||||||
*
|
|
||||||
* @param variant
|
|
||||||
* Which variant of checkers will this game be.
|
|
||||||
*/
|
|
||||||
public Game(int variant) {
|
|
||||||
this(variant, new Player(), new Player());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new game.
|
|
||||||
*
|
|
||||||
* @param variant
|
|
||||||
* The variant of checkers to be played.
|
|
||||||
* @param light
|
|
||||||
* The player playing the light side.
|
|
||||||
* @param dark
|
|
||||||
* The player playing the dark side.
|
|
||||||
*/
|
|
||||||
public Game(int variant, Player light, Player dark) {
|
|
||||||
// Setup all the components of the game.
|
|
||||||
this.gameRules = new Rulebook(variant);
|
|
||||||
this.gameBoard = new Board(this.gameRules);
|
|
||||||
this.darkPlayer = dark;
|
|
||||||
this.lightPlayer = light;
|
|
||||||
|
|
||||||
// Setup the board and start the game.
|
|
||||||
this.lightPlayerTurn = this.gameRules.isLightPlayerFirst();
|
|
||||||
this.gameBoard.setupNewGame();
|
|
||||||
this.jumpInProgress = null; // No moves in progress yet.
|
|
||||||
this.gameState = Game.STATE_GAME_IN_PROGRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add a constructor for games already in progress.
|
|
||||||
|
|
||||||
// -- Game methods --------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player playing the dark side.
|
|
||||||
*
|
|
||||||
* @return The player playing the dark side.
|
|
||||||
*/
|
|
||||||
public Player getDarkPlayer() {
|
|
||||||
return this.darkPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Get/Set Methods ------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Gets the board used for this game.
|
|
||||||
*
|
|
||||||
* @return The board used for this game.
|
|
||||||
*/
|
|
||||||
public Board getGameBoard() {
|
|
||||||
return this.gameBoard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the rules used for this game.
|
|
||||||
*
|
|
||||||
* @return The rules used for this game.
|
|
||||||
*/
|
|
||||||
public Rulebook getGameRules() {
|
|
||||||
return this.gameRules;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the state of the game. The state is defined by the STATE_*
|
|
||||||
* constants.
|
|
||||||
*
|
|
||||||
* @return The state of the game.
|
|
||||||
*/
|
|
||||||
public int getGameState() {
|
|
||||||
return this.gameState;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player playing the light side.
|
|
||||||
*
|
|
||||||
* @return The player playing the light side.
|
|
||||||
*/
|
|
||||||
public Player getLightPlayer() {
|
|
||||||
return this.lightPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if it is the light player's turn. Returns false if it is the dark
|
|
||||||
* player's turn.
|
|
||||||
*
|
|
||||||
* @return If it is the light player's turn. Returns false if it is the dark
|
|
||||||
* player's turn.
|
|
||||||
*/
|
|
||||||
public boolean isLightPlayerTurn() {
|
|
||||||
return this.lightPlayerTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the player playing the dark side.
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* The player playing the dark side.
|
|
||||||
*/
|
|
||||||
public void setDarkPlayer(Player player) {
|
|
||||||
this.darkPlayer = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the board used for this game.
|
|
||||||
*
|
|
||||||
* @param board
|
|
||||||
* The board for this game.
|
|
||||||
*/
|
|
||||||
public void setGameBoard(Board board) {
|
|
||||||
this.gameBoard = board;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Private Methods ------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the rules used for this game.
|
|
||||||
*
|
|
||||||
* @param rules
|
|
||||||
* The rules used for this game.
|
|
||||||
*/
|
|
||||||
public void setGameRules(Rulebook rules) {
|
|
||||||
this.gameRules = rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the state of the game. The state is defined by the STATE_*
|
|
||||||
* constants.
|
|
||||||
*
|
|
||||||
* @param state
|
|
||||||
* The state of the game.
|
|
||||||
*/
|
|
||||||
public void setGameState(int state) {
|
|
||||||
this.gameState = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the player playing the light side.
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* The player playing the light side.
|
|
||||||
*/
|
|
||||||
public void setLightPlayer(Player player) {
|
|
||||||
this.lightPlayer = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets if it is the light player's turn. Set it to false if its the dark
|
|
||||||
* player's turn.
|
|
||||||
*
|
|
||||||
* @param playerTurn
|
|
||||||
* If it is the light player's turn.
|
|
||||||
*/
|
|
||||||
public void setLightPlayerTurn(boolean playerTurn) {
|
|
||||||
this.lightPlayerTurn = playerTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the jumpInProgress
|
|
||||||
*/
|
|
||||||
public IPoint getJumpInProgress() {
|
|
||||||
return jumpInProgress;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,295 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GameEngine.java -- Logic engine for manipulating the state of a game.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author dpula
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GameEngine {
|
|
||||||
|
|
||||||
// TODO: Add a constructor for games already in progress.
|
|
||||||
|
|
||||||
// -- Game methods --------------------------------------------------------
|
|
||||||
|
|
||||||
private static boolean canJump(Game game, int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
// TODO: Implement me.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if a piece can or cannot move. This move maybe either be a move
|
|
||||||
* or a jump. This method is called by a user interface when a user wants to
|
|
||||||
* moves a piece on screen or over the network. The piece can moved if the
|
|
||||||
* current state of the game allows for it to do so.
|
|
||||||
*
|
|
||||||
* TODO: Add priority for king jumps over pawn jumps for any variants that
|
|
||||||
* do so.
|
|
||||||
*
|
|
||||||
* @param sourceRow
|
|
||||||
* The row from where the piece is moving from.
|
|
||||||
* @param sourceCol
|
|
||||||
* The column from where the piece is moving from.
|
|
||||||
* @param targetRow
|
|
||||||
* The row to where the piece is moving to.
|
|
||||||
* @param targetCol
|
|
||||||
* The column to where the piece is moving to.
|
|
||||||
* @return True if the piece can move. False if the piece can not move.
|
|
||||||
*/
|
|
||||||
public static boolean canMove(Game game, int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
// A few things to figure out priorities in moving a piece.
|
|
||||||
boolean legalMove = false; // Is the proposed move/jump legal?
|
|
||||||
boolean realPositions = false; // Are the positions really on the board?
|
|
||||||
boolean isJump = false; // Is this a jump?
|
|
||||||
|
|
||||||
// Sanity check.
|
|
||||||
if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
|
|
||||||
&& game.getGameBoard().isLegalPosition(targetRow, targetCol)) {
|
|
||||||
realPositions = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is there a jump in progress?
|
|
||||||
if (realPositions && game.getJumpInProgress() != null) {
|
|
||||||
|
|
||||||
// Only allow the piece in movement to be moved.
|
|
||||||
if (sourceRow == game.getJumpInProgress().getY()
|
|
||||||
&& sourceCol == game.getJumpInProgress().getX()) {
|
|
||||||
legalMove = canJump(game, sourceRow, sourceCol, targetRow,
|
|
||||||
targetCol);
|
|
||||||
isJump = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (realPositions) {
|
|
||||||
|
|
||||||
// Go with the regular flow, jumps first then "slides".
|
|
||||||
isJump = canPlayerJump(game);
|
|
||||||
if (isJump) {
|
|
||||||
legalMove = canJump(game, sourceRow, sourceCol, targetRow,
|
|
||||||
targetCol);
|
|
||||||
} else {
|
|
||||||
legalMove = canSlide(game, sourceRow, sourceCol, targetRow,
|
|
||||||
targetCol);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return legalMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean canPlayerJump(Game game) {
|
|
||||||
// TODO: Implement me.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean canSlide(Game game, int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
boolean legalMove = true;
|
|
||||||
boolean mustJump = canPlayerJump(game);
|
|
||||||
|
|
||||||
// Is the move even on the board?
|
|
||||||
legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
|
|
||||||
&& game.getGameBoard().isLegalPosition(targetRow, targetCol);
|
|
||||||
|
|
||||||
// See if the destination is even empty.
|
|
||||||
if (legalMove) {
|
|
||||||
legalMove = game.getGameBoard().isEmpty(targetRow, targetCol);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If yes, then look if right pieces were chosen.
|
|
||||||
if (legalMove && !mustJump) {
|
|
||||||
if (game.isLightPlayerTurn()
|
|
||||||
&& game.getGameBoard().isLight(sourceRow, sourceCol)) {
|
|
||||||
|
|
||||||
// To deal with flying kings.
|
|
||||||
if (game.getGameBoard().isKing(sourceRow, sourceCol)
|
|
||||||
&& game.getGameRules().canKingsFly()) {
|
|
||||||
|
|
||||||
// FIXME: Fix this!
|
|
||||||
} else {
|
|
||||||
// if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) {
|
|
||||||
// legalMove = false;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the path clear for that move?
|
|
||||||
|
|
||||||
} else if (!game.isLightPlayerTurn()
|
|
||||||
&& game.getGameBoard().isDark(sourceRow, sourceCol)) {
|
|
||||||
|
|
||||||
//TODO: Implement me, sometime.
|
|
||||||
} else {
|
|
||||||
legalMove = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return legalMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkForVictory(Game game) {
|
|
||||||
// TODO: Implement me.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if a piece is movable. Returns true if the piece can slide or jump.
|
|
||||||
* This method only calculates slides to the adjacent positions. Similarly,
|
|
||||||
* the method only looks at jumping an adjacent enemy piece. This check is
|
|
||||||
* used by the graphical user interface to determine if a piece can be moved
|
|
||||||
* either for sliding or jumping. The method is aware of whose turn is it to
|
|
||||||
* move.
|
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
* The row coordinate of the piece to check.
|
|
||||||
* @param col
|
|
||||||
* The column coordinate of the piece to check.
|
|
||||||
* @return Returns true if the piece can slide or jump in this turn.
|
|
||||||
*/
|
|
||||||
public static boolean isMovablePiece(Game game, int row, int col) {
|
|
||||||
|
|
||||||
// Fields for determining of a piece is movable.
|
|
||||||
boolean moveUpLeft = true;
|
|
||||||
boolean moveUpRight = true;
|
|
||||||
boolean moveDownLeft = true;
|
|
||||||
boolean moveDownRight = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks first if the first colour of piece is being grabbed. Next if
|
|
||||||
* the piece is blocked by its own pieces. Next if the opponent has
|
|
||||||
* double blocked off the pieces. Also sanity checks if looking past the
|
|
||||||
* size of the board.
|
|
||||||
*/
|
|
||||||
if (game.isLightPlayerTurn() && game.getGameBoard().isLight(row, col)) { // Light
|
|
||||||
// player.
|
|
||||||
|
|
||||||
// Can piece move normally?
|
|
||||||
moveDownLeft = canSlide(game, row, col, row + 1, col - 1);
|
|
||||||
moveDownRight = canSlide(game, row, col, row + 1, col + 1);
|
|
||||||
|
|
||||||
if (game.getGameBoard().isKing(row, col)) {
|
|
||||||
moveUpLeft = canSlide(game, row, col, row - 1, col - 1);
|
|
||||||
moveUpRight = canSlide(game, row, col, row - 1, col + 1);
|
|
||||||
} else {
|
|
||||||
moveUpLeft = false;
|
|
||||||
moveUpRight = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no slides available try doing the same except for jumps.
|
|
||||||
if (!moveDownLeft) {
|
|
||||||
moveDownLeft = canJump(game, row, col, row + 2, col - 2);
|
|
||||||
} else if (!moveDownRight) {
|
|
||||||
moveDownRight = canJump(game, row, col, row + 2, col + 2);
|
|
||||||
} else if (game.getGameBoard().isKing(row, col)
|
|
||||||
|| game.getGameRules().canPawnsJumpBackwards()) {
|
|
||||||
|
|
||||||
if (!moveUpLeft) {
|
|
||||||
moveUpLeft = canJump(game, row, col, row - 2, col + 2);
|
|
||||||
} else if (!moveUpRight) {
|
|
||||||
moveUpRight = canJump(game, row, col, row - 2, col - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight;
|
|
||||||
|
|
||||||
} else if (game.isLightPlayerTurn() && game.getGameBoard().isDark(row, col)) { // Dark
|
|
||||||
// player
|
|
||||||
|
|
||||||
// Can piece move normally?
|
|
||||||
moveUpLeft = canSlide(game, row, col, row - 1, col - 1);
|
|
||||||
moveUpRight = canSlide(game, row, col, row - 1, col + 1);
|
|
||||||
|
|
||||||
if (game.getGameBoard().isKing(row, col)) {
|
|
||||||
moveDownLeft = canSlide(game, row, col, row + 1, col - 1);
|
|
||||||
moveDownRight = canSlide(game, row, col, row + 1, col + 1);
|
|
||||||
} else {
|
|
||||||
moveDownLeft = false;
|
|
||||||
moveDownRight = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no slides available try doing the same except for jumps.
|
|
||||||
if (!moveUpLeft) {
|
|
||||||
moveUpLeft = canJump(game, row, col, row - 2, col - 2);
|
|
||||||
} else if (!moveUpRight) {
|
|
||||||
moveUpRight = canJump(game, row, col, row - 2, col + 2);
|
|
||||||
} else if (game.getGameBoard().isKing(row, col)
|
|
||||||
|| game.getGameRules().canPawnsJumpBackwards()) {
|
|
||||||
|
|
||||||
if (!moveDownLeft) {
|
|
||||||
moveDownLeft = canJump(game, row, col, row + 2, col + 2);
|
|
||||||
} else if (!moveDownRight) {
|
|
||||||
moveDownRight = canJump(game, row, col, row + 2, col - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false; // A wrong coloured piece.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves a pieces from one location to another. This move maybe either be a
|
|
||||||
* move or a jump. This method is called by a user interface when a user
|
|
||||||
* moves a piece on screen or over the network. The piece is moved if the
|
|
||||||
* current state of the game allows for it to do so.
|
|
||||||
*
|
|
||||||
* TODO: Add priority for king jumps over pawn jumps for any variants that
|
|
||||||
* do so. TODO: Implement jumping by piece removal.
|
|
||||||
*
|
|
||||||
* @param sourceRow
|
|
||||||
* The row from where the piece is moving from.
|
|
||||||
* @param sourceCol
|
|
||||||
* The column from where the piece is moving from.
|
|
||||||
* @param targetRow
|
|
||||||
* The row to where the piece is moving to.
|
|
||||||
* @param targetCol
|
|
||||||
* The column to where the piece is moving to.
|
|
||||||
*/
|
|
||||||
public static void movePiece(Game game, int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
// If everything checks out... move the piece!
|
|
||||||
if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)) {
|
|
||||||
if (game.getJumpInProgress() != null) {
|
|
||||||
|
|
||||||
// TODO: Implement jumping via removing of piece.
|
|
||||||
game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
|
|
||||||
targetCol);
|
|
||||||
} else {
|
|
||||||
game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
|
|
||||||
targetCol);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForVictory(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author dorian
|
|
||||||
* Created 2013-04-03 @ 4:59 PM by IntelliJ IDEA.
|
|
||||||
*/
|
|
||||||
public interface IPoint {
|
|
||||||
|
|
||||||
public void setX(double x);
|
|
||||||
public void setY(double y);
|
|
||||||
public double getX();
|
|
||||||
public double getY();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
Player.java -- Data objects for maintaining player information.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manages the information of a single player.
|
|
||||||
*
|
|
||||||
* @author Chris Bellini
|
|
||||||
* @author Dorian Pula
|
|
||||||
*/
|
|
||||||
public class Player {
|
|
||||||
|
|
||||||
/** The player's total number of losses. */
|
|
||||||
private int gamesLost;
|
|
||||||
/** The total number of games played by the player. */
|
|
||||||
private int gamesPlayed;
|
|
||||||
/** The player's total number of ties. */
|
|
||||||
private int gamesTied;
|
|
||||||
/** The player's total number of wins. */
|
|
||||||
private int gamesWon;
|
|
||||||
/** The player's name. */
|
|
||||||
private final String playerName;
|
|
||||||
|
|
||||||
/** Creates an unnamed player with a blank record. */
|
|
||||||
public Player() {
|
|
||||||
this("Unnamed Player", 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a player with a given name and a blank record.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* The name of the player.
|
|
||||||
*/
|
|
||||||
public Player(String name) {
|
|
||||||
this(name, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a player with a given name and record.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* The name of the player to be created.
|
|
||||||
* @param wins
|
|
||||||
* Player's total wins.
|
|
||||||
* @param losses
|
|
||||||
* Player's total losses.
|
|
||||||
* @param ties
|
|
||||||
* Player's total ties.
|
|
||||||
* @param played
|
|
||||||
* Total games played by the player.
|
|
||||||
*/
|
|
||||||
public Player(String name, int wins, int losses, int ties, int played) {
|
|
||||||
this.playerName = name;
|
|
||||||
this.gamesWon = wins;
|
|
||||||
this.gamesLost = losses;
|
|
||||||
this.gamesTied = ties;
|
|
||||||
this.gamesPlayed = played;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a new loss for the player's total losses. */
|
|
||||||
public void addLoss() {
|
|
||||||
this.gamesLost++;
|
|
||||||
this.gamesPlayed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a new tie for the player's total ties. */
|
|
||||||
public void addTie() {
|
|
||||||
this.gamesTied++;
|
|
||||||
this.gamesPlayed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a new win for the player's total wins. */
|
|
||||||
public void addWin() {
|
|
||||||
this.gamesWon++;
|
|
||||||
this.gamesPlayed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's total losses.
|
|
||||||
*
|
|
||||||
* @return The player's total losses.
|
|
||||||
*/
|
|
||||||
public int getLosses() {
|
|
||||||
return this.gamesLost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the total number of games played by the player.
|
|
||||||
*
|
|
||||||
* @return The total number of games played by the player.
|
|
||||||
*/
|
|
||||||
public int getPlayedGames() {
|
|
||||||
return this.gamesPlayed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's total score.
|
|
||||||
*
|
|
||||||
* @return The player's total score.
|
|
||||||
*/
|
|
||||||
public int getTies() {
|
|
||||||
return this.gamesTied;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's total wins.
|
|
||||||
*
|
|
||||||
* @return The player's total wins.
|
|
||||||
*/
|
|
||||||
public int getWins() {
|
|
||||||
return this.gamesWon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints all the data about the player.
|
|
||||||
*
|
|
||||||
* @return A string representing the player's data.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Name: " + this.playerName + "\n" + "Games: Won "
|
|
||||||
+ this.gamesWon + " Lost " + this.gamesLost + " Tied "
|
|
||||||
+ this.gamesTied;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,352 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
Rulebook.java -- A generic 'rulebook' for a checkers game.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The rules for a game of checkers. This class provides a reference object for
|
|
||||||
* a game of checkers. This helps deal with the number of variants of checkers.
|
|
||||||
* One of the goals of justCheckers is to provide the flexibility of choose
|
|
||||||
* between different kinds of checker variants. This class builds a skeleton of
|
|
||||||
* the rules by defining what setup, moves, jumps, victory conditions and
|
|
||||||
* special moves make up a particular variant of checkers.
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
* @author Chris Bellini
|
|
||||||
*/
|
|
||||||
public class Rulebook {
|
|
||||||
|
|
||||||
// -- Constants -----------------------------------------------------------
|
|
||||||
|
|
||||||
// Checkers variants.
|
|
||||||
/** Playing by the American rules. */
|
|
||||||
public static final int AMERICAN_CHECKERS = 0;
|
|
||||||
/** Playing by International (Polish) rules. */
|
|
||||||
public static final int INTERNATIONAL_CHECKERS = 1;
|
|
||||||
/** Playing by the Brazilian rules. */
|
|
||||||
public static final int BRAZILIAN_CHECKERS = 2;
|
|
||||||
/** Playing by the Canadian rules. */
|
|
||||||
public static final int CANADIAN_CHECKERS = 3;
|
|
||||||
/** Playing by Pool (Southern USA) rules. */
|
|
||||||
public static final int POOL_CHECKERS = 4;
|
|
||||||
/** Playing by the Spanish rules. */
|
|
||||||
public static final int SPANISH_CHECKERS = 5;
|
|
||||||
/** Playing by the Russian rules. */
|
|
||||||
public static final int RUSSIAN_CHECKERS = 6;
|
|
||||||
/** Playing by the Italian rules. */
|
|
||||||
public static final int ITALIAN_CHECKERS = 7;
|
|
||||||
/** Playing by Suicide rules. */
|
|
||||||
public static final int SUICIDE_CHECKERS = 8;
|
|
||||||
/** Playing by the Ghanaian rules. */
|
|
||||||
public static final int GHANAIAN_CHECKERS = 9;
|
|
||||||
|
|
||||||
// TODO: Implement special rules for these checkers. Version >0.1.1?
|
|
||||||
// Victory conditions.
|
|
||||||
/** Victory achieved by capturing all enemy pieces. */
|
|
||||||
public static final int CAPTURE_ALL_ENEMIES_VICTORY = 0;
|
|
||||||
/**
|
|
||||||
* Victory achieved by capturing all pieces. Only caveat is the three king
|
|
||||||
* versus one king draw rule:
|
|
||||||
*
|
|
||||||
* In many games at the end one adversary has three kings while the other
|
|
||||||
* one has just one king. In such a case the first adversary must win in
|
|
||||||
* thirteen moves or the game is declared a draw. (Shamelessly stolen from
|
|
||||||
* http://en.wikipedia.org/wiki/Draughts).
|
|
||||||
*/
|
|
||||||
public static final int SPECIAL_POOL_VICTORY = 1;
|
|
||||||
/** Victory achieved some bizarre manner. TODO: Figure out Russian checkers. */
|
|
||||||
public static final int SPECIAL_RUSSIAN_VICTORY = 2;
|
|
||||||
/** Victory achieved by losing all your pieces. */
|
|
||||||
public static final int SPECIAL_SUICIDE_VICTORY = 3;
|
|
||||||
/** Victory achieved by not being the first with one piece left. */
|
|
||||||
public static final int SPECIAL_GHANAIAN_VICTORY = 4;
|
|
||||||
|
|
||||||
// Checker board sizes.
|
|
||||||
/** Using a "standard" American checkers board. */
|
|
||||||
public static final int STANDARD_BOARD_SIZE = 8;
|
|
||||||
/** Using an international sized checkers board. */
|
|
||||||
public static final int INTERNATIONAL_BOARD_SIZE = 10;
|
|
||||||
/** Using a Canadian sized checkers board. */
|
|
||||||
public static final int CANADIAN_BOARD_SIZE = 12;
|
|
||||||
|
|
||||||
/** The number of variants currently supported. */
|
|
||||||
private static final int NUMBER_OF_VARIANTS_SUPPORTED = 2;
|
|
||||||
|
|
||||||
/** The size of the board. */
|
|
||||||
private int boardSize;
|
|
||||||
/** Can kings fly across the board? */
|
|
||||||
private boolean canKingsFly;
|
|
||||||
/** Can pawns capture backwards? */
|
|
||||||
private boolean canPawnsJumpBackwards;
|
|
||||||
|
|
||||||
// -- Object Fields --------------------------------------------------------
|
|
||||||
/** Stores what kind of checkers variant of rule are we playing? */
|
|
||||||
private int checkersVariant;
|
|
||||||
/** Does the light player start first? */
|
|
||||||
private boolean lightPlayerFirst;
|
|
||||||
/** Is the board mirrored? As in white square lower right corner. */
|
|
||||||
private boolean mirroredBoard;
|
|
||||||
/** Must capture if have opportunity. */
|
|
||||||
private boolean mustCapture;
|
|
||||||
/** Must player capture the highest number of pieces. */
|
|
||||||
private boolean mustCaptureMaxium;
|
|
||||||
/** The type of victory conditions. */
|
|
||||||
private int victoryConditions;
|
|
||||||
|
|
||||||
// -- Constructors ---------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Creates a rulebook for a checkers game. We use the American variant rules
|
|
||||||
* by default.
|
|
||||||
*/
|
|
||||||
public Rulebook() {
|
|
||||||
this(Rulebook.AMERICAN_CHECKERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a rulebook for a checkers game. If a bad/unsupported variant is
|
|
||||||
* created, the default of American checkers is chosen.
|
|
||||||
*
|
|
||||||
* @param variant
|
|
||||||
* The variant of checkers we will play.
|
|
||||||
*/
|
|
||||||
public Rulebook(int variant) {
|
|
||||||
if (variant >= 0 && variant < Rulebook.NUMBER_OF_VARIANTS_SUPPORTED) {
|
|
||||||
this.checkersVariant = variant;
|
|
||||||
} else {
|
|
||||||
this.checkersVariant = Rulebook.AMERICAN_CHECKERS;
|
|
||||||
}
|
|
||||||
this.setUpRules();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if kings can fly. That is can kings move as far they wish.
|
|
||||||
*
|
|
||||||
* @return If kings can fly.
|
|
||||||
*/
|
|
||||||
public boolean canKingsFly() {
|
|
||||||
return this.canKingsFly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if pawns can capture backwards.
|
|
||||||
*
|
|
||||||
* @return If pawns can capture backwards.
|
|
||||||
*/
|
|
||||||
public boolean canPawnsJumpBackwards() {
|
|
||||||
return this.canPawnsJumpBackwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the size of the board.
|
|
||||||
*
|
|
||||||
* @return The size of the board.
|
|
||||||
*/
|
|
||||||
public int getBoardSize() {
|
|
||||||
return this.boardSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Get/set methods ------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Returns the checkers variant being played.
|
|
||||||
*
|
|
||||||
* @return The checkers variant being played.
|
|
||||||
*/
|
|
||||||
public int getCheckersVariant() {
|
|
||||||
return this.checkersVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the victory conditions of this game.
|
|
||||||
*
|
|
||||||
* @return The victory conditions of this game.
|
|
||||||
*/
|
|
||||||
public int getVictoryConditions() {
|
|
||||||
return this.victoryConditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns is the board mirrored in this game.
|
|
||||||
*
|
|
||||||
* @return Is the board mirrored in this game.
|
|
||||||
*/
|
|
||||||
public boolean isBoardMirrored() {
|
|
||||||
return this.mirroredBoard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if the light player starts the game.
|
|
||||||
*
|
|
||||||
* @return If the light player starts the game.
|
|
||||||
*/
|
|
||||||
public boolean isLightPlayerFirst() {
|
|
||||||
return this.lightPlayerFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if you must capture a piece if you can.
|
|
||||||
*
|
|
||||||
* @return If you must capture a piece if you can.
|
|
||||||
*/
|
|
||||||
public boolean mustCapture() {
|
|
||||||
return this.mustCapture;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if you must capture the maximum number of pieces possible.
|
|
||||||
*
|
|
||||||
* @return If you must capture the maximum number of pieces possible.
|
|
||||||
*/
|
|
||||||
public boolean mustCaptureMaxium() {
|
|
||||||
return this.mustCaptureMaxium;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Private implementation methods.
|
|
||||||
/**
|
|
||||||
* Setups the rules according to what variant of checkers was chosen.
|
|
||||||
*/
|
|
||||||
private void setUpRules() {
|
|
||||||
// Save my sanity.
|
|
||||||
assert this.checkersVariant >= 0;
|
|
||||||
assert this.checkersVariant < Rulebook.NUMBER_OF_VARIANTS_SUPPORTED;
|
|
||||||
|
|
||||||
// Set up the rules by the type of variant.
|
|
||||||
switch (this.checkersVariant) {
|
|
||||||
case Rulebook.AMERICAN_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = false;
|
|
||||||
this.canPawnsJumpBackwards = false;
|
|
||||||
this.lightPlayerFirst = false;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = false;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.INTERNATIONAL_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.INTERNATIONAL_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = true;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.BRAZILIAN_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = true;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.CANADIAN_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.CANADIAN_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = false;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.POOL_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = false;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = false;
|
|
||||||
this.victoryConditions = Rulebook.SPECIAL_POOL_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.SPANISH_CHECKERS:
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = false;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = true;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = true;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.RUSSIAN_CHECKERS:
|
|
||||||
// TODO: Needs special freshly-kinged-but-still-can-jump special
|
|
||||||
// rule.
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = false;
|
|
||||||
this.victoryConditions = Rulebook.SPECIAL_RUSSIAN_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.ITALIAN_CHECKERS:
|
|
||||||
// TODO: Special rule on must jump most number of kings per capture.
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
// TODO: Special rule that pawns can't capture kings.
|
|
||||||
this.canPawnsJumpBackwards = false;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = true;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = true;
|
|
||||||
this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.SUICIDE_CHECKERS:
|
|
||||||
// TODO: Needs unconventional setup.
|
|
||||||
this.boardSize = Rulebook.STANDARD_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = false;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = true;
|
|
||||||
this.victoryConditions = Rulebook.SPECIAL_SUICIDE_VICTORY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Rulebook.GHANAIAN_CHECKERS:
|
|
||||||
// TODO: Special forfeit king if passing up a king's capture
|
|
||||||
// opportunity.
|
|
||||||
this.boardSize = Rulebook.INTERNATIONAL_BOARD_SIZE;
|
|
||||||
this.canKingsFly = true;
|
|
||||||
this.canPawnsJumpBackwards = true;
|
|
||||||
this.lightPlayerFirst = true;
|
|
||||||
this.mirroredBoard = true;
|
|
||||||
this.mustCapture = true;
|
|
||||||
this.mustCaptureMaxium = false;
|
|
||||||
this.victoryConditions = Rulebook.SPECIAL_GHANAIAN_VICTORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds the justCheckers configuration settings.
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
|
|
||||||
final public class ConfigSettings extends Settings{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Fields //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
private static ConfigSettings cs = null;
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//======= PUBLIC ============//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor method for obtaining the one
|
|
||||||
* and only instance of this class
|
|
||||||
*/
|
|
||||||
public static ConfigSettings getInstance(){
|
|
||||||
if(cs==null) cs = new ConfigSettings(new DefaultConfigSettings());
|
|
||||||
return cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the default config settings.
|
|
||||||
*/
|
|
||||||
public static void loadDefault(){
|
|
||||||
cs = new ConfigSettings(new DefaultConfigSettings());
|
|
||||||
}
|
|
||||||
|
|
||||||
//======= PRIVATE CONSTRUCTORS ========//
|
|
||||||
private ConfigSettings(){
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigSettings(DefaultConfigSettings cus){
|
|
||||||
super(cus.getTextMap(),cus.getAttributeMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
//======= PRIVATE INNER CLASS ============//
|
|
||||||
|
|
||||||
/* The default class from which to get settings */
|
|
||||||
private static class DefaultConfigSettings extends Settings.DefaultSettings{
|
|
||||||
private String userHome = System.getProperty("user.home");
|
|
||||||
private String userDir = System.getProperty("user.dir");
|
|
||||||
private String [][] text =
|
|
||||||
{
|
|
||||||
{"configsettings.directory.configFile",userDir+"/config.xml"},
|
|
||||||
{"configsettings.directory.settings",userHome+"/settings/"},
|
|
||||||
{"configsettings.directory.skins",userDir+"/skins/"},
|
|
||||||
{"configsettings.directory.sounds",userDir+"/sounds/"},
|
|
||||||
{"configsettings.directory.language",userDir+"/language/"},
|
|
||||||
};
|
|
||||||
|
|
||||||
private String [][] attribute =
|
|
||||||
{
|
|
||||||
{"configsettings.general.id","3"},
|
|
||||||
{"configsettings.general.id2","5"},
|
|
||||||
{"configsettings.language.default","english"},
|
|
||||||
{"configsettings.appearance.pretty","true"},
|
|
||||||
};
|
|
||||||
|
|
||||||
DefaultConfigSettings(){
|
|
||||||
super();
|
|
||||||
super.setFields(text,attribute);
|
|
||||||
}
|
|
||||||
}//end of default class
|
|
||||||
}
|
|
|
@ -1,295 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import org.jdom.Attribute;
|
|
||||||
import org.jdom.Comment;
|
|
||||||
import org.jdom.Document;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.JDOMException;
|
|
||||||
import org.jdom.input.SAXBuilder;
|
|
||||||
import org.jdom.output.XMLOutputter;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concrete child class of the XML_IO class. Use its load() and save() methods
|
|
||||||
* to write XML into/write out XML from, the associated ConfigSettings object.
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
public class ConfigSettingsIO extends XML_IO{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Interface -------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the XML data held within the File object referenced by the member
|
|
||||||
* variable "file" (inherited from XML_IO) to be loaded into the ConfigSettings
|
|
||||||
* object associated with this class. The reading in of XML data and subsequent
|
|
||||||
* transformation is dealt with by the inner reader class of this class.
|
|
||||||
*/
|
|
||||||
public void load(){
|
|
||||||
try{
|
|
||||||
SAXBuilder builder = new SAXBuilder();
|
|
||||||
Document doc = builder.build(getFile());
|
|
||||||
Element rootElement = doc.getRootElement();
|
|
||||||
ConfigSettingsIOReader csior = new ConfigSettingsIOReader();
|
|
||||||
csior.visit(rootElement);
|
|
||||||
}
|
|
||||||
// catch(IOException e){
|
|
||||||
// String msg = "Problem : " + e.getMessage();
|
|
||||||
// Log.e("ConfigSettingsIO", msg);
|
|
||||||
// }
|
|
||||||
catch(JDOMException e){
|
|
||||||
String msg = "Problem : " + getFile().toString()
|
|
||||||
+ " is not a well formed XML document";
|
|
||||||
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(UserSettingsIO.class);
|
|
||||||
log.error("ConfigSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the data held within the ConfigSettings object associated with
|
|
||||||
* this class to be saved as XML format into the File object referenced by
|
|
||||||
* the member variable "file". Transformation of ConfigSettings data into XML
|
|
||||||
* format and subsequent writing to file is handled by the inner writer
|
|
||||||
* class of this class.
|
|
||||||
*/
|
|
||||||
public void save(){
|
|
||||||
try{
|
|
||||||
ConfigSettingsIOWriter csiow = new ConfigSettingsIOWriter();
|
|
||||||
Document doc = csiow.createXMLDocument();
|
|
||||||
XMLOutputter outputter = new XMLOutputter("",true);
|
|
||||||
PrintWriter pw = new PrintWriter(
|
|
||||||
new BufferedWriter(
|
|
||||||
new FileWriter(getFile())));
|
|
||||||
outputter.output(doc,pw);
|
|
||||||
}
|
|
||||||
catch(IOException e){
|
|
||||||
String msg = "Problem : couldn't output to the given file : "
|
|
||||||
+ getFile().toString();
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(ConfigSettingsIO.class);
|
|
||||||
log.error("ConfigSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Contructors -----------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor used to initiate the ConfigSettingsIO
|
|
||||||
* object with a given file object
|
|
||||||
* @param fileObject The file object with which
|
|
||||||
* to initiate this ConfigSettingsIO.
|
|
||||||
*/
|
|
||||||
public ConfigSettingsIO(File fileObject){
|
|
||||||
super(fileObject,ConfigSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigSettingsIO(File fileObject, ConfigSettings cs){
|
|
||||||
super(fileObject,cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigSettingsIO(URL urlObject){
|
|
||||||
super(urlObject, ConfigSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigSettingsIO(URL urlObject, ConfigSettings cs){
|
|
||||||
super(urlObject,cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : READER //
|
|
||||||
///////////////////////////////////
|
|
||||||
|
|
||||||
private class ConfigSettingsIOReader extends XML_IO.XMLFileReader{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads text information held in an Element object
|
|
||||||
* into the ConfigSettings object
|
|
||||||
*/
|
|
||||||
protected void loadElementIntoSettings(Element e){
|
|
||||||
String text = e.getTextTrim();
|
|
||||||
if(text!=null && text.length()!=0){
|
|
||||||
ConfigSettings.getInstance().setElementText(toFullSettingName(e),text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads Attribute information held in an Element object
|
|
||||||
* into the ConfigSettings object
|
|
||||||
*/
|
|
||||||
protected void loadAttributesIntoSettings(Element e){
|
|
||||||
List attributes = e.getAttributes();
|
|
||||||
ConfigSettings cs = ConfigSettings.getInstance();
|
|
||||||
for(int k=0;k<attributes.size();k++){
|
|
||||||
Attribute current = (Attribute)attributes.get(k);
|
|
||||||
|
|
||||||
String total = toFullSettingName(e) + "" + current.getName();
|
|
||||||
cs.setElementAttribute(total,current.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the correct number on the end of the settings key.
|
|
||||||
Thus a.b.c.d becomes a.b.c.d.x where x=1,2,3...Checks if the key
|
|
||||||
a.b.c.d.1 exists. If so, looks for a.b.c.d.2, etc. in the settings class,
|
|
||||||
and so on, until it has a new key. This method thus allows multi Elements
|
|
||||||
with the same name to be stored uniquely. Without this, for example,
|
|
||||||
game moves would all have the same key e.g. gamesettings.game.move
|
|
||||||
*/
|
|
||||||
protected String correctKeyForNumber(String uncorrectedKey){
|
|
||||||
int i = 1;
|
|
||||||
String correctedKey = uncorrectedKey + "" + i;
|
|
||||||
//is there a key with this name?
|
|
||||||
boolean reachedEnd = (ConfigSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
while(!reachedEnd){
|
|
||||||
i++;
|
|
||||||
int lastDotIndex = correctedKey.lastIndexOf('.');
|
|
||||||
correctedKey = correctedKey.substring(0,lastDotIndex+1) + i;
|
|
||||||
reachedEnd = (ConfigSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return correctedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //end of inner class ConfigSettingsIOReader
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : WRITER //
|
|
||||||
///////////////////////////////////
|
|
||||||
private class ConfigSettingsIOWriter extends XML_IO.XMLFileWriter{
|
|
||||||
/* Creates and returns the Document root Element */
|
|
||||||
public Element createRootElement(){
|
|
||||||
ConfigSettings cs = ConfigSettings.getInstance();
|
|
||||||
Iterator textEntries = cs.getTextEntries().iterator();
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
return new Element((String)settingKeyTokens.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Comment objects to the current Document */
|
|
||||||
public void addComments(Document doc){
|
|
||||||
String text = "This file is important. Do not delete it,"
|
|
||||||
+ " do not displace it, do not rename it. Do any of these things"
|
|
||||||
+ " and as the universe is our witness we'll fry your ass, your"
|
|
||||||
+ " hard drive, sleep with your girlfriend (and she'll enjoy it,"
|
|
||||||
+ " believe us!), have you fired from your job, and transfer your"
|
|
||||||
+ " bank accounts to our names. Yes; this program is that good.";
|
|
||||||
doc.addContent(new Comment(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the JDOM tree from the ConfigSettings class */
|
|
||||||
public void addElements(Element rootElement){
|
|
||||||
ConfigSettings cs = ConfigSettings.getInstance();
|
|
||||||
Iterator textEntries = cs.getTextEntries().iterator();
|
|
||||||
//iterator returns Map.Entry objects
|
|
||||||
while(textEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
Element parent = rootElement;
|
|
||||||
Element child = null;
|
|
||||||
for(int k=1;k<settingKeyTokens.size();k++){
|
|
||||||
String childName = (String)settingKeyTokens.get(k);
|
|
||||||
child = getChildElement(parent,childName);
|
|
||||||
if(child==null){
|
|
||||||
child = new Element(childName);
|
|
||||||
parent.addContent(child);
|
|
||||||
if(isLastToken(k,settingKeyTokens.size())){
|
|
||||||
child.addContent(settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Attribute objects to the DOM tree Elements */
|
|
||||||
public void addAttributes(Element root){
|
|
||||||
Iterator attributeEntries =
|
|
||||||
ConfigSettings.getInstance().getAttributeEntries().iterator();
|
|
||||||
|
|
||||||
while(attributeEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)attributeEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
Element e = getElement(settingKeyTokens,root);
|
|
||||||
e.setAttribute((String)settingKeyTokens.get(
|
|
||||||
settingKeyTokens.size()-1),settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks whether the token from the StringTokenizer operation
|
|
||||||
private boolean isLastToken(int k, int listSize){
|
|
||||||
return (k==listSize-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Navigates down the jdom tree until it reaches the element
|
|
||||||
//to which we wish to attach an attribute. Returns that element.
|
|
||||||
private Element getElement(ArrayList tokens, Element root){
|
|
||||||
Element e = root;
|
|
||||||
for(int k=1;k<tokens.size()-1;k++){
|
|
||||||
e = e.getChild((String)tokens.get(k));
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does this parent Element already have a child with this name attached?
|
|
||||||
* If so, return it, else return null
|
|
||||||
*/
|
|
||||||
private Element getChildElement(Element parent, String childName){
|
|
||||||
return parent.getChild(childName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Splits a Setting key of the form a.b.c.d into it's
|
|
||||||
respective parts, delimited by the "." */
|
|
||||||
private ArrayList splitSettingKey(String key){
|
|
||||||
ArrayList l = new ArrayList();
|
|
||||||
StringTokenizer st = new StringTokenizer(key, "",false);
|
|
||||||
while(st.hasMoreTokens()){
|
|
||||||
l.add(st.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
}//end of inner class ConfigSettingsIOWriter
|
|
||||||
|
|
||||||
}//end of class ConfigSettingsIO
|
|
|
@ -1,68 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds the current game settings (Players, moves, etc).
|
|
||||||
* Currently, only one game may be open at a time.
|
|
||||||
* Future versions may allow more than one game to be open at
|
|
||||||
* a given moment.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
final public class GameSettings extends Settings{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Fields //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
private HashMap text = new HashMap(), attribute = new HashMap();
|
|
||||||
private static GameSettings gs = null;
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//======= PUBLIC ============//
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor method for reaching the one and only instance of this class.
|
|
||||||
* @return Reference to the GameSettings object
|
|
||||||
*/
|
|
||||||
public static GameSettings getInstance(){
|
|
||||||
if(gs==null) gs = new GameSettings();
|
|
||||||
return gs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================ NOTE : ===============================================
|
|
||||||
=======================================================================
|
|
||||||
For GameSettings, we need in addition to the inherited Settings methods
|
|
||||||
methods that will be used to fill this object when a new game is started.
|
|
||||||
To be able to code these required methods (there will be more than the two
|
|
||||||
I give as example below) we need to agree on a format for games XML files.
|
|
||||||
|
|
||||||
public void addMove(CheckersMove cm){...}
|
|
||||||
public void addPlayer(Player p){...}
|
|
||||||
...
|
|
||||||
...
|
|
||||||
...
|
|
||||||
=========================================================================
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -- Private Constructors -----------------------------------------------
|
|
||||||
|
|
||||||
private GameSettings(){
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,297 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import org.jdom.Attribute;
|
|
||||||
import org.jdom.Comment;
|
|
||||||
import org.jdom.Document;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.JDOMException;
|
|
||||||
import org.jdom.input.SAXBuilder;
|
|
||||||
import org.jdom.output.XMLOutputter;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/* **************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concrete child class of the @link(XML_IO) class. Represents an
|
|
||||||
* "intelligent" XML file that can read XML data into/write data from
|
|
||||||
* the @link(GameSettings) information associated with this class.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
public class GameSettingsIO extends XML_IO{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Interface -------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the XML data held within the File object referenced by the member
|
|
||||||
* variable "file" (inherited from XML_IO) to be loaded into the GameSettings
|
|
||||||
* object associated with this class. The reading in of XML data and subsequent
|
|
||||||
* transformation is dealt with by the inner reader class of this class.
|
|
||||||
*/
|
|
||||||
public void load(){
|
|
||||||
try{
|
|
||||||
SAXBuilder builder = new SAXBuilder();
|
|
||||||
Document doc = builder.build(getFile());
|
|
||||||
Element rootElement = doc.getRootElement();
|
|
||||||
GameSettingsIOReader gsior = new GameSettingsIOReader();
|
|
||||||
gsior.visit(rootElement);
|
|
||||||
}
|
|
||||||
//catch(IOException e){
|
|
||||||
// String msg = "Problem : " + e.getMessage();
|
|
||||||
// Log.e("GameSettingsIO", msg);
|
|
||||||
//}
|
|
||||||
catch(JDOMException e){
|
|
||||||
String msg = "Problem : " + getFile().toString()
|
|
||||||
+ " is not a well formed XML document";
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(GameSettingsIO.class);
|
|
||||||
log.error("GameSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the data held within the GameSettings object associated with
|
|
||||||
* this class to be saved as XML format into the File object referenced by
|
|
||||||
* the member variable "file". Transformation of GameSettings data into XML
|
|
||||||
* format and subsequent writing to file is handled by the inner writer
|
|
||||||
* class of this class.
|
|
||||||
*/
|
|
||||||
public void save(){
|
|
||||||
try{
|
|
||||||
GameSettingsIOWriter gsiow = new GameSettingsIOWriter();
|
|
||||||
Document doc = gsiow.createXMLDocument();
|
|
||||||
XMLOutputter outputter = new XMLOutputter("",true);
|
|
||||||
PrintWriter pw = new PrintWriter(
|
|
||||||
new BufferedWriter(
|
|
||||||
new FileWriter(getFile())));
|
|
||||||
outputter.output(doc,pw);
|
|
||||||
}
|
|
||||||
catch(IOException e){
|
|
||||||
String msg = "Problem : couldn't output to the given file : "
|
|
||||||
+ getFile().toString();
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(GameSettingsIO.class);
|
|
||||||
log.error("GameSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Contructors -----------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor used to initiate the GameSettingsIO
|
|
||||||
* object with a given file object
|
|
||||||
* @param fileObject The file object with which
|
|
||||||
* to initiate this GameSettingsIO.
|
|
||||||
*/
|
|
||||||
public GameSettingsIO(File fileObject){
|
|
||||||
super(fileObject,GameSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameSettingsIO(File fileObject, GameSettings cs){
|
|
||||||
super(fileObject,cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameSettingsIO(URL urlObject){
|
|
||||||
super(urlObject, GameSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameSettingsIO(URL urlObject, GameSettings cs){
|
|
||||||
super(urlObject,cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : READER //
|
|
||||||
///////////////////////////////////
|
|
||||||
|
|
||||||
private class GameSettingsIOReader extends XML_IO.XMLFileReader{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads text information held in an Element object
|
|
||||||
* into the GameSettings object
|
|
||||||
*/
|
|
||||||
protected void loadElementIntoSettings(Element e){
|
|
||||||
String text = e.getTextTrim();
|
|
||||||
if(text!=null && text.length()!=0){
|
|
||||||
GameSettings.getInstance().setElementText(toFullSettingName(e),text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads Attribute information held in an Element object
|
|
||||||
* into the GameSettings object
|
|
||||||
*/
|
|
||||||
protected void loadAttributesIntoSettings(Element e){
|
|
||||||
List attributes = e.getAttributes();
|
|
||||||
GameSettings gs = GameSettings.getInstance();
|
|
||||||
for(int k=0;k<attributes.size();k++){
|
|
||||||
Attribute current = (Attribute)attributes.get(k);
|
|
||||||
|
|
||||||
String total = toFullSettingName(e) + "" + current.getName();
|
|
||||||
gs.setElementAttribute(total,current.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the correct number on the end of the settings key.
|
|
||||||
Thus a.b.c.d becomes a.b.c.d.x where x=1,2,3...Checks if the key
|
|
||||||
a.b.c.d.1 exists. If so, looks for a.b.c.d.2, etc. in the settings class,
|
|
||||||
and so on, until it has a new key. This method thus allows multi Elements
|
|
||||||
with the same name to be stored uniquely. Without this, for example,
|
|
||||||
game moves would all have the same key e.g. gamesettings.game.move
|
|
||||||
*/
|
|
||||||
protected String correctKeyForNumber(String uncorrectedKey){
|
|
||||||
int i = 1;
|
|
||||||
String correctedKey = uncorrectedKey + "" + i;
|
|
||||||
//is there a key with this name?
|
|
||||||
boolean reachedEnd = (GameSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
while(!reachedEnd){
|
|
||||||
i++;
|
|
||||||
int lastDotIndex = correctedKey.lastIndexOf('.');
|
|
||||||
correctedKey = correctedKey.substring(0,lastDotIndex+1) + i;
|
|
||||||
reachedEnd = (GameSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return correctedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //end of inner class GameSettingsIOReader
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : WRITER //
|
|
||||||
///////////////////////////////////
|
|
||||||
private class GameSettingsIOWriter extends XML_IO.XMLFileWriter{
|
|
||||||
/* Creates and returns the Document root Element */
|
|
||||||
public Element createRootElement(){
|
|
||||||
GameSettings gs = GameSettings.getInstance();
|
|
||||||
Iterator textEntries = gs.getTextEntries().iterator();
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
return new Element((String)settingKeyTokens.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Comment objects to the current Document */
|
|
||||||
public void addComments(Document doc){
|
|
||||||
String text = "This file is important. Do not delete it,"
|
|
||||||
+ " do not displace it, do not rename it. Do any of these things"
|
|
||||||
+ " and as the universe is our witness we'll fry your ass, your"
|
|
||||||
+ " hard drive, sleep with your girlfriend (and she'll enjoy it,"
|
|
||||||
+ " believe us!), have you fired from your job, and transfer your"
|
|
||||||
+ " bank accounts to our names. Yes; this program is that good.";
|
|
||||||
doc.addContent(new Comment(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the JDOM tree from the GameSettings class */
|
|
||||||
public void addElements(Element rootElement){
|
|
||||||
GameSettings gs = GameSettings.getInstance();
|
|
||||||
Iterator textEntries = gs.getTextEntries().iterator();
|
|
||||||
//iterator returns Map.Entry objects
|
|
||||||
while(textEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
Element parent = rootElement;
|
|
||||||
Element child = null;
|
|
||||||
for(int k=1;k<settingKeyTokens.size();k++){
|
|
||||||
String childName = (String)settingKeyTokens.get(k);
|
|
||||||
child = getChildElement(parent,childName);
|
|
||||||
if(child==null){
|
|
||||||
child = new Element(childName);
|
|
||||||
parent.addContent(child);
|
|
||||||
if(isLastToken(k,settingKeyTokens.size())){
|
|
||||||
child.addContent(settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Attribute objects to the DOM tree Elements */
|
|
||||||
public void addAttributes(Element root){
|
|
||||||
Iterator attributeEntries =
|
|
||||||
GameSettings.getInstance().getAttributeEntries().iterator();
|
|
||||||
|
|
||||||
while(attributeEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)attributeEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
Element e = getElement(settingKeyTokens,root);
|
|
||||||
e.setAttribute((String)settingKeyTokens.get(
|
|
||||||
settingKeyTokens.size()-1),settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks whether the token from the StringTokenizer operation
|
|
||||||
private boolean isLastToken(int k, int listSize){
|
|
||||||
return (k==listSize-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Navigates down the jdom tree until it reaches the element
|
|
||||||
//to which we wish to attach an attribute. Returns that element.
|
|
||||||
private Element getElement(ArrayList tokens, Element root){
|
|
||||||
Element e = root;
|
|
||||||
for(int k=1;k<tokens.size()-1;k++){
|
|
||||||
e = e.getChild((String)tokens.get(k));
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does this parent Element already have a child with this name attached?
|
|
||||||
* If so, return it, else return null
|
|
||||||
*/
|
|
||||||
private Element getChildElement(Element parent, String childName){
|
|
||||||
return parent.getChild(childName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Splits a Setting key of the form a.b.c.d into it's
|
|
||||||
respective parts, delimited by the "." */
|
|
||||||
private ArrayList splitSettingKey(String key){
|
|
||||||
ArrayList l = new ArrayList();
|
|
||||||
StringTokenizer st = new StringTokenizer(key, "",false);
|
|
||||||
while(st.hasMoreTokens()){
|
|
||||||
l.add(st.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
}//end of inner class GameSettingsIOWriter
|
|
||||||
|
|
||||||
}//end of class GameSettingsIO
|
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines a common template for all classes that
|
|
||||||
* store some sort of Settings. Text, Attribute and Element
|
|
||||||
* are references to the XML objects as implemented
|
|
||||||
* by the JDOM API (http://www.jdom.org).
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
public abstract class Settings{
|
|
||||||
//---------------------------//
|
|
||||||
// Class Fields //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
protected HashMap text = null, attribute = null;
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Interface -------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
public static void loadDefault(){}
|
|
||||||
|
|
||||||
//get/set methods on the HashMaps
|
|
||||||
public String getElementText(String key){
|
|
||||||
if(!text.containsKey(key)) return null;
|
|
||||||
return (String)text.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setElementText(String key, String value){
|
|
||||||
text.put(key,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getElementAttribute(String key){
|
|
||||||
if(!attribute.containsKey(key)) return null;
|
|
||||||
return (String)attribute.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setElementAttribute(String key, String value){
|
|
||||||
attribute.put(key,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSetting(String key){
|
|
||||||
if(text.containsKey(key)) return getElementText(key);
|
|
||||||
else if(attribute.containsKey(key)) return getElementAttribute(key);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set getTextEntries(){return text.entrySet();}
|
|
||||||
public Set getAttributeEntries(){return attribute.entrySet();}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Constructors ----------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected Settings(){
|
|
||||||
text = new HashMap();
|
|
||||||
attribute = new HashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate the two class HashMap member objects with the parameters
|
|
||||||
* @param t The HashMap with which to initiate the "text" member
|
|
||||||
* @param a The HashMap with which to initiate the "attribute" member
|
|
||||||
*/
|
|
||||||
protected Settings(HashMap t, HashMap a){
|
|
||||||
text = t;
|
|
||||||
attribute = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// INNER CLASS : Default Settings //
|
|
||||||
////////////////////////////////////
|
|
||||||
/**
|
|
||||||
* The outer Settings object employs this nested one to obtain default values
|
|
||||||
* for its member HashMap objects "text" and "attribute".
|
|
||||||
*/
|
|
||||||
protected abstract static class DefaultSettings{
|
|
||||||
//------ Class Fields -----------
|
|
||||||
protected String [][] text = {};
|
|
||||||
protected String [][] attribute = {};
|
|
||||||
|
|
||||||
//------ Class Methods ----------
|
|
||||||
protected void setFields(String [][] text, String [][] attribute){
|
|
||||||
this.text = text;
|
|
||||||
this.attribute = attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap getTextMap(){
|
|
||||||
HashMap hm = new HashMap(text.length);
|
|
||||||
for(int k=0;k<text.length;k++){
|
|
||||||
hm.put(text[k][0],text[k][1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap getAttributeMap(){
|
|
||||||
HashMap hm = new HashMap(attribute.length);
|
|
||||||
for(int k=0;k<attribute.length;k++){
|
|
||||||
hm.put(attribute[k][0],attribute[k][1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the user preferences in the application memory.
|
|
||||||
* Implements the singleton pattern.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
final public class UserSettings extends Settings{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Fields //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
private static UserSettings us = null;
|
|
||||||
private HashMap text = null, attribute = null;
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
// -- Interface ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor method for obtaining the one and only instance of this class
|
|
||||||
*/
|
|
||||||
public static UserSettings getInstance(){
|
|
||||||
if(us==null) loadDefault();
|
|
||||||
return us;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the default user settings.
|
|
||||||
*/
|
|
||||||
public static void loadDefault(){
|
|
||||||
us = new UserSettings(new DefaultUserSettings());
|
|
||||||
//somehow would have to log that properties have changed
|
|
||||||
//so that things can be updated e.g. the UI, or whatever
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Private Constructors -----------------------------------------------
|
|
||||||
|
|
||||||
private UserSettings(){
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserSettings(DefaultUserSettings dus){
|
|
||||||
super(dus.getTextMap(), dus.getAttributeMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// INNER CLASS : DefaultSettings //
|
|
||||||
//////////////////////////////////////
|
|
||||||
|
|
||||||
private static class DefaultUserSettings extends Settings.DefaultSettings{
|
|
||||||
private String [][] text =
|
|
||||||
{
|
|
||||||
{"usersettings.general.splashOnLaunch","true"},
|
|
||||||
{"usersettings.general.maxActiveGames","3"},
|
|
||||||
{"usersettings.audio.activateBkgdOnLaunch","false"},
|
|
||||||
{"usersettings.audio.defaultBkgdSong","song1.wav"},
|
|
||||||
{"usersettings.audio.appSoundsActive","true"},
|
|
||||||
{"usersettings.language.current","english"},
|
|
||||||
{"usersettings.appearance.fullScreenOnLaunch","true"},
|
|
||||||
{"usersettings.appearance.activePieceSet","pieceset1"},
|
|
||||||
};
|
|
||||||
|
|
||||||
private String [][] attribute =
|
|
||||||
{
|
|
||||||
{"usersettings.general.id","3"},
|
|
||||||
{"usersettings.general.id2","5"},
|
|
||||||
{"usersettings.language.default","english"},
|
|
||||||
{"usersettings.appearance.pretty","true"},
|
|
||||||
};
|
|
||||||
|
|
||||||
DefaultUserSettings(){
|
|
||||||
super();
|
|
||||||
super.setFields(text,attribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,302 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import org.jdom.Attribute;
|
|
||||||
import org.jdom.Comment;
|
|
||||||
import org.jdom.Document;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.JDOMException;
|
|
||||||
import org.jdom.input.SAXBuilder;
|
|
||||||
import org.jdom.output.XMLOutputter;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/* **************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concrete child class of the @link(XML_IO) class. Represents an
|
|
||||||
* "intelligent" XML file that can read XML data into/write data from
|
|
||||||
* the @link(UserSettings) information associated with this class.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
public class UserSettingsIO extends XML_IO {
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Interface -------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the XML data held within the File object referenced by the member
|
|
||||||
* variable "file" (inherited from XML_IO) to be loaded into the UserSettings
|
|
||||||
* object associated with this class. The reading in of XML data and subsequent
|
|
||||||
* transformation is dealt with by the inner reader class of this class.
|
|
||||||
*/
|
|
||||||
public void load(){
|
|
||||||
try{
|
|
||||||
SAXBuilder builder = new SAXBuilder();
|
|
||||||
Document doc = builder.build(getFile());
|
|
||||||
Element rootElement = doc.getRootElement();
|
|
||||||
UserSettingsIOReader usior = new UserSettingsIOReader();
|
|
||||||
usior.visit(rootElement);
|
|
||||||
}
|
|
||||||
// catch(IOException e){
|
|
||||||
// String msg = "Problem : " + e.getMessage();
|
|
||||||
// Log.e("UserSettingsIO", msg);
|
|
||||||
// }
|
|
||||||
catch(JDOMException e){
|
|
||||||
String msg = "Problem : " + getFile().toString()
|
|
||||||
+ " is not a well formed XML document";
|
|
||||||
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(UserSettingsIO.class);
|
|
||||||
log.error("UserSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the data held within the UserSettings object associated with
|
|
||||||
* this class to be saved as XML format into the File object referenced by
|
|
||||||
* the member variable "file". Transformation of UserSettings data into XML
|
|
||||||
* format and subsequent writing to file is handled by the inner writer
|
|
||||||
* class of this class.
|
|
||||||
*/
|
|
||||||
public void save(){
|
|
||||||
try{
|
|
||||||
UserSettingsIOWriter usiow = new UserSettingsIOWriter();
|
|
||||||
Document doc = usiow.createXMLDocument();
|
|
||||||
XMLOutputter outputter = new XMLOutputter("",true);
|
|
||||||
PrintWriter pw = new PrintWriter(
|
|
||||||
new BufferedWriter(
|
|
||||||
new FileWriter(getFile())));
|
|
||||||
outputter.output(doc,pw);
|
|
||||||
}
|
|
||||||
catch(IOException e){
|
|
||||||
String msg = "Problem : couldn't output to the given file : "
|
|
||||||
+ getFile().toString();
|
|
||||||
|
|
||||||
// TODO Clean up...
|
|
||||||
Logger log = LoggerFactory.getLogger(UserSettingsIO.class);
|
|
||||||
log.error("UserSettingsIO", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Contructors -----------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor used to initiate the UserSettingsIO
|
|
||||||
* object with a given file object
|
|
||||||
* @param fileObject The file object with which
|
|
||||||
* to initiate this UserSettingsIO.
|
|
||||||
*/
|
|
||||||
public UserSettingsIO(File fileObject){
|
|
||||||
super(fileObject,UserSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSettingsIO(File fileObject, UserSettings us){
|
|
||||||
super(fileObject,us);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSettingsIO(URL urlObject){
|
|
||||||
super(urlObject,UserSettings.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserSettingsIO(URL urlObject, UserSettings us){
|
|
||||||
super(urlObject,us);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : READER //
|
|
||||||
///////////////////////////////////
|
|
||||||
|
|
||||||
private class UserSettingsIOReader extends XML_IO.XMLFileReader{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads text information held in an Element object
|
|
||||||
* into the UserSettings object
|
|
||||||
*/
|
|
||||||
protected void loadElementIntoSettings(Element e){
|
|
||||||
String text = e.getTextTrim();
|
|
||||||
if(text!=null && text.length()!=0){
|
|
||||||
String fullName = toFullSettingName(e);
|
|
||||||
UserSettings.getInstance().setElementText(fullName,text);
|
|
||||||
System.out.println("element: " + fullName + " = " + text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads Attribute information held in an Element object
|
|
||||||
* into the UserSettings object
|
|
||||||
*/
|
|
||||||
protected void loadAttributesIntoSettings(Element e){
|
|
||||||
List attributes = e.getAttributes();
|
|
||||||
UserSettings us = UserSettings.getInstance();
|
|
||||||
for(int k=0;k<attributes.size();k++){
|
|
||||||
Attribute current = (Attribute)attributes.get(k);
|
|
||||||
|
|
||||||
String total = toFullSettingName(e) + "" + current.getName();
|
|
||||||
us.setElementAttribute(total,current.getValue());
|
|
||||||
System.out.println("attribute: " + total + " = " + current.getValue());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the correct number on the end of the settings key.
|
|
||||||
Thus a.b.c.d becomes a.b.c.d.x where x=1,2,3...Checks if the key
|
|
||||||
a.b.c.d.1 exists. If so, looks for a.b.c.d.2, etc. in the settings class,
|
|
||||||
and so on, until it has a new key. This method thus allows multi Elements
|
|
||||||
with the same name to be stored uniquely. Without this, for example,
|
|
||||||
game moves would all have the same key e.g. gamesettings.game.move
|
|
||||||
*/
|
|
||||||
protected String correctKeyForNumber(String uncorrectedKey){
|
|
||||||
int i = 1;
|
|
||||||
String correctedKey = uncorrectedKey + "" + i;
|
|
||||||
//is there a key with this name?
|
|
||||||
boolean reachedEnd = (UserSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
while(!reachedEnd){
|
|
||||||
i++;
|
|
||||||
int lastDotIndex = correctedKey.lastIndexOf('.');
|
|
||||||
correctedKey = correctedKey.substring(0,lastDotIndex+1) + i;
|
|
||||||
reachedEnd = (UserSettings.getInstance().getElementText(correctedKey) == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return correctedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //end of inner class UserSettingsIOReader
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : WRITER //
|
|
||||||
///////////////////////////////////
|
|
||||||
private class UserSettingsIOWriter extends XML_IO.XMLFileWriter{
|
|
||||||
/* Creates and returns the Document root Element */
|
|
||||||
public Element createRootElement(){
|
|
||||||
UserSettings us = UserSettings.getInstance();
|
|
||||||
Iterator textEntries = us.getTextEntries().iterator();
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
return new Element((String)settingKeyTokens.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Comment objects to the current Document */
|
|
||||||
public void addComments(Document doc){
|
|
||||||
String text = "This file is important. Do not delete it,"
|
|
||||||
+ " do not displace it, do not rename it. Do any of these things"
|
|
||||||
+ " and as the universe is our witness we'll fry your ass, your"
|
|
||||||
+ " hard drive, sleep with your girlfriend (and she'll enjoy it,"
|
|
||||||
+ " believe us!), have you fired from your job, and transfer your"
|
|
||||||
+ " bank accounts to our names. Yes; this program is that good.";
|
|
||||||
doc.addContent(new Comment(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the JDOM tree from the UserSettings class */
|
|
||||||
public void addElements(Element rootElement){
|
|
||||||
UserSettings us = UserSettings.getInstance();
|
|
||||||
Iterator textEntries = us.getTextEntries().iterator();
|
|
||||||
//iterator returns Map.Entry objects
|
|
||||||
while(textEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)textEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
|
|
||||||
Element parent = rootElement;
|
|
||||||
Element child = null;
|
|
||||||
for(int k=1;k<settingKeyTokens.size();k++){
|
|
||||||
String childName = (String)settingKeyTokens.get(k);
|
|
||||||
child = getChildElement(parent,childName);
|
|
||||||
if(child==null){
|
|
||||||
child = new Element(childName);
|
|
||||||
parent.addContent(child);
|
|
||||||
if(isLastToken(k,settingKeyTokens.size())){
|
|
||||||
child.addContent(settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adds org.jdom.Attribute objects to the DOM tree Elements */
|
|
||||||
public void addAttributes(Element root){
|
|
||||||
Iterator attributeEntries =
|
|
||||||
UserSettings.getInstance().getAttributeEntries().iterator();
|
|
||||||
|
|
||||||
while(attributeEntries.hasNext()){
|
|
||||||
Map.Entry me = (Map.Entry)attributeEntries.next();
|
|
||||||
String settingKey = (String)me.getKey();
|
|
||||||
String settingValue = (String)me.getValue();
|
|
||||||
ArrayList settingKeyTokens = splitSettingKey(settingKey);
|
|
||||||
Element e = getElement(settingKeyTokens,root);
|
|
||||||
e.setAttribute((String)settingKeyTokens.get(
|
|
||||||
settingKeyTokens.size()-1),settingValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks whether the token from the StringTokenizer operation
|
|
||||||
private boolean isLastToken(int k, int listSize){
|
|
||||||
return (k==listSize-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Navigates down the jdom tree until it reaches the element
|
|
||||||
//to which we wish to attach an attribute. Returns that element.
|
|
||||||
private Element getElement(ArrayList tokens, Element root){
|
|
||||||
Element e = root;
|
|
||||||
for(int k=1;k<tokens.size()-1;k++){
|
|
||||||
e = e.getChild((String)tokens.get(k));
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does this parent Element already have a child with this name attached?
|
|
||||||
* If so, return it, else return null
|
|
||||||
*/
|
|
||||||
private Element getChildElement(Element parent, String childName){
|
|
||||||
return parent.getChild(childName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Splits a Setting key of the form a.b.c.d into it's
|
|
||||||
respective parts, delimited by the "." */
|
|
||||||
private ArrayList splitSettingKey(String key){
|
|
||||||
ArrayList l = new ArrayList();
|
|
||||||
StringTokenizer st = new StringTokenizer(key, "",false);
|
|
||||||
while(st.hasMoreTokens()){
|
|
||||||
l.add(st.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
}//end of inner class UserSettingsIOWriter
|
|
||||||
|
|
||||||
}//end of class UserSettingsIO
|
|
|
@ -1,102 +0,0 @@
|
||||||
//********************************************************************
|
|
||||||
// VisitDOM.java -- Abstract class for traversing XML documents.
|
|
||||||
// ********************************************************************
|
|
||||||
|
|
||||||
// ********************************************************************
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
// ********************************************************************
|
|
||||||
|
|
||||||
package org.justcheckers.xml;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.Text;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract class that provides a framework to do any processing of a
|
|
||||||
* DOM tree created with the JDOM package ( http://www.jdom.org ). It
|
|
||||||
* provides a recursive traverse with data processing methods that run
|
|
||||||
* before traversal, after traversal and at each Element object and Text
|
|
||||||
* object encountered. The default methods are do-nothing place-holders.
|
|
||||||
* These methods can be over-ridden in a child class that extends this one,
|
|
||||||
* doing what ever data processing needs to be done. Other methods and
|
|
||||||
* fields can also be added to child classes as needed.
|
|
||||||
*
|
|
||||||
* @author Dan D'Alimonte
|
|
||||||
*/
|
|
||||||
public abstract class VisitDOM {
|
|
||||||
|
|
||||||
// -- Interface ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform before the traversal of the DOM tree begins.
|
|
||||||
* @param e The root Element of the tree.
|
|
||||||
*/
|
|
||||||
protected void preRoot(Element e) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform after the traversal has been completed.
|
|
||||||
* @param e The root Element of the tree.
|
|
||||||
*/
|
|
||||||
protected void postRoot(Element e) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform when an Element object is encountered in the DOM tree.
|
|
||||||
* @param e The Element object to process.
|
|
||||||
*/
|
|
||||||
protected void elementHandler(Element e) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform when a Text object is encountered in the DOM tree.
|
|
||||||
* @param t The Text object to process.
|
|
||||||
*/
|
|
||||||
protected void textHandler(Text t) {}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Contructors -------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new VisitDOM instance.
|
|
||||||
*/
|
|
||||||
public VisitDOM() {}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Public methods ----------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preform the taversal on the DOM tree, visiting each node and
|
|
||||||
* processing them in turn.
|
|
||||||
* @param root The root Element of the tree to preform the traversal on.
|
|
||||||
*/
|
|
||||||
public void visit(Element root) {
|
|
||||||
preRoot(root);
|
|
||||||
elementHandler(root);
|
|
||||||
recurse(root);
|
|
||||||
postRoot(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Protected Methods -------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Traverses to children of Elements, calling appropriate data processing
|
|
||||||
* methods on the child objects, recursing deeper if needed.
|
|
||||||
* @param e The element whose children are to be processed.
|
|
||||||
*/
|
|
||||||
protected void recurse(Element e) {
|
|
||||||
Iterator iElement = e.getChildren().iterator();
|
|
||||||
while (iElement.hasNext()) {
|
|
||||||
Object next = iElement.next();
|
|
||||||
if (next instanceof Element) {
|
|
||||||
elementHandler((Element)next);
|
|
||||||
recurse((Element)next);
|
|
||||||
}
|
|
||||||
else if ( next instanceof Text ) {
|
|
||||||
textHandler((Text)next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileFilter;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XMLFileFilter returns only File objects that represent XML files.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class XMLFileFilter implements FileFilter{
|
|
||||||
public boolean accept(File f){
|
|
||||||
return f.toString().endsWith(".xml");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,267 +0,0 @@
|
||||||
package org.justcheckers.xml;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import org.jdom.Document;
|
|
||||||
import org.jdom.Element;
|
|
||||||
import org.jdom.Text;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
|
||||||
* (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract version of an "intelligent" XML file. Objects of this class know
|
|
||||||
* how to read/write the @see(Settings) information they are associated with,
|
|
||||||
* into justCheckers memory/out to disk. The user creates a child object of
|
|
||||||
* this class giving the name and location of the File object to be represented
|
|
||||||
* by this class.
|
|
||||||
*
|
|
||||||
* NOTE :
|
|
||||||
* For the time being, data may only be outputted to XML files stored locally.
|
|
||||||
*
|
|
||||||
* @author Brinick Simmons (brinick@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
public abstract class XML_IO{
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Fields //
|
|
||||||
//---------------------------//
|
|
||||||
//protected URL url;
|
|
||||||
protected File file;
|
|
||||||
protected Settings settings;
|
|
||||||
|
|
||||||
//---------------------------//
|
|
||||||
// Class Methods //
|
|
||||||
//---------------------------//
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Interface -------------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the XML data held within the File object referenced by the class
|
|
||||||
* member variable "file" to be loaded into the Settings object associated
|
|
||||||
* with this class. The reading in of XML data and subsequent transformation
|
|
||||||
* is dealt with by the inner reader class of this class.
|
|
||||||
*/
|
|
||||||
public abstract void load();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes the data held within the Settings object associated with this class
|
|
||||||
* to be saved as XML format into the File object referenced by the class
|
|
||||||
* member variable "file". Transformation of Settings data to XML format and
|
|
||||||
* subsequent writing to File is handled by the inner writer class of this
|
|
||||||
* class.
|
|
||||||
*/
|
|
||||||
public abstract void save();
|
|
||||||
|
|
||||||
/** Sets the member variable File object to the parameter object passed in.
|
|
||||||
* @param f The File object with which to set the class member variable "file"
|
|
||||||
*/
|
|
||||||
protected void setFile(File f){file = f;}
|
|
||||||
|
|
||||||
/** Gets the member variable File object.
|
|
||||||
* @return The File object held in the class member variable "file".
|
|
||||||
*/
|
|
||||||
protected File getFile(){return file;}
|
|
||||||
|
|
||||||
/* Place holder for a later version */
|
|
||||||
// protected void setFile(URL u){}
|
|
||||||
// protected URL getFile(){}
|
|
||||||
|
|
||||||
/** Sets the member variable Settings object to the parameter object passed in.
|
|
||||||
* @param s The Settings object with which to set the class member variable "settings"
|
|
||||||
*/
|
|
||||||
protected void setSettings(Settings s){settings = s;}
|
|
||||||
|
|
||||||
/** Gets the member variable Settings object.
|
|
||||||
* @return The Settings object held in the class member variable "settings".
|
|
||||||
*/
|
|
||||||
protected Settings getSettings(){return settings;}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// -- Constructors ----------------------------------------------------
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected XML_IO(){}
|
|
||||||
protected XML_IO(File f, Settings s){file = f; settings=s;}
|
|
||||||
protected XML_IO(URL u, Settings s){}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : READER //
|
|
||||||
///////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract class that provides a framework to do any processing of a
|
|
||||||
* DOM tree created with the JDOM package ( http://www.jdom.org ). It
|
|
||||||
* provides a recursive traverse with data processing methods that run
|
|
||||||
* before traversal, after traversal and at each Element object and Text
|
|
||||||
* object encountered. The default methods are do-nothing place-holders.
|
|
||||||
* These methods can be over-ridden in a child class that extends this one,
|
|
||||||
* doing what ever data processing needs to be done. Other methods and
|
|
||||||
* fields can also be added to child classes as needed.
|
|
||||||
*
|
|
||||||
* @author Dan D'Alimonte (skwirl@users.sourceforge.net)
|
|
||||||
*/
|
|
||||||
protected abstract class XMLFileReader{
|
|
||||||
|
|
||||||
// -- Interface ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform before the traversal of the DOM tree begins.
|
|
||||||
* @param e The root Element of the tree.
|
|
||||||
*/
|
|
||||||
protected void preRoot( Element e ) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform after the traversal has been completed.
|
|
||||||
* @param e The root Element of the tree.
|
|
||||||
*/
|
|
||||||
protected void postRoot( Element e ) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform when an Element object is encountered in the DOM tree.
|
|
||||||
* @param e The Element object to process.
|
|
||||||
*/
|
|
||||||
protected void elementHandler( Element e ) {
|
|
||||||
loadElementIntoSettings(e);
|
|
||||||
loadAttributesIntoSettings(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void loadElementIntoSettings(Element e);
|
|
||||||
protected abstract void loadAttributesIntoSettings(Element e);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions to preform when a Text object is encountered in the DOM tree.
|
|
||||||
* @param t The Text object to process.
|
|
||||||
*/
|
|
||||||
protected void textHandler( Text t ) {}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Constructors -------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new VisitDOM instance.
|
|
||||||
*/
|
|
||||||
public XMLFileReader() {}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Public methods ----------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preform the traversal on the DOM tree, visiting each node and
|
|
||||||
* processing them in turn.
|
|
||||||
* @param root The root Element of the tree to preform the traversal on.
|
|
||||||
*/
|
|
||||||
public void visit( Element root ) {
|
|
||||||
preRoot( root );
|
|
||||||
elementHandler( root );
|
|
||||||
recurse( root );
|
|
||||||
postRoot( root );
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Protected Methods -------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Traverses to children of Elements, calling appropriate data processing
|
|
||||||
* methods on the child objects, recursing deeper if needed.
|
|
||||||
* @param e The element whose children are to be processed.
|
|
||||||
*/
|
|
||||||
protected void recurse( Element e ) {
|
|
||||||
Iterator iElement = e.getChildren().iterator();
|
|
||||||
while ( iElement.hasNext() ) {
|
|
||||||
Object next = iElement.next();
|
|
||||||
if ( next instanceof Element ) {
|
|
||||||
elementHandler( (Element)next );
|
|
||||||
recurse( (Element)next );
|
|
||||||
}
|
|
||||||
else if ( next instanceof Text ) {
|
|
||||||
textHandler( (Text)next );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the full path name in the form a.b.c.d
|
|
||||||
* of an Element object d
|
|
||||||
*/
|
|
||||||
protected String toFullSettingName(Element e){
|
|
||||||
String path = e.getName();
|
|
||||||
Element currentElement = e;
|
|
||||||
while(!currentElement.isRootElement()){
|
|
||||||
currentElement = currentElement.getParent();
|
|
||||||
path = currentElement.getName() + "" + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return correctKeyForNumber(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract String correctKeyForNumber(String path);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// INNER CLASS : WRITER //
|
|
||||||
///////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract framework for creating a DOM tree
|
|
||||||
* (using the JDOM API http://www.jdom.org) from an
|
|
||||||
* in-application memory "Settings" class.
|
|
||||||
* The default methods are do-nothing place-holders
|
|
||||||
* that should be over-ridden by a child class.
|
|
||||||
* @author Brinick Simmons
|
|
||||||
* @see UserSettings
|
|
||||||
* @see GameSettings
|
|
||||||
*/
|
|
||||||
protected abstract class XMLFileWriter{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns a JDOM Document object
|
|
||||||
* @return org.jdom.Document object storing Settings information
|
|
||||||
*/
|
|
||||||
protected Document createXMLDocument(){
|
|
||||||
Element root = createRootElement();
|
|
||||||
Document doc = new Document(root);
|
|
||||||
addComments(doc);
|
|
||||||
addElements(root);
|
|
||||||
addAttributes(root);
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the root org.jdom.Element for the Document in memory
|
|
||||||
* @return The newly created root Element
|
|
||||||
*/
|
|
||||||
abstract protected Element createRootElement();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds org.jdom.Comment objects to the Document
|
|
||||||
* @param d The Document to which Comments will be added
|
|
||||||
*/
|
|
||||||
protected void addComments(Document d){}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the tree structure of org.jdom.Element objects in the Document.
|
|
||||||
* @param root The tree root Element to which all other
|
|
||||||
* Elements are (in)directly attached.
|
|
||||||
*/
|
|
||||||
protected void addElements(Element root){}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds any org.jdom.Attribute objects to the appropriate Element objects.
|
|
||||||
* @param root The tree root Element.
|
|
||||||
*/
|
|
||||||
protected void addAttributes(Element root){}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
AmericanGameTest.java -- Regression test of a game played according to
|
|
||||||
American rules.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.test.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Regression test for a game of checkers played according to American rules.
|
|
||||||
* American rules are:
|
|
||||||
* - 8x8 board.
|
|
||||||
* - Pawns can only move 1 space forward.
|
|
||||||
* - Kings can move 1 space forward or backwards.
|
|
||||||
* - The game ends when one player is eliminated or completely blocked.
|
|
||||||
*
|
|
||||||
* TestNG version: 5.10
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AmericanGameTest {
|
|
||||||
//TODO: Populate with test cases.
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GameLogicTest.java -- Unit tests related to the game engine.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.test.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the game engine logic. Tests if the game engine can manipulate the
|
|
||||||
* state of a game and its board, in accordance to the rules of the game. The
|
|
||||||
* set of rule change from variant to variant. These tests should check basic
|
|
||||||
* correctness of the game engine.
|
|
||||||
*
|
|
||||||
* TestNG version: 5.10
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GameLogicTest {
|
|
||||||
//TODO: Populate with test cases.
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
GameStateTest.java -- Unit tests related to managing a game's state.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.test.game;
|
|
||||||
|
|
||||||
import org.justcheckers.game.Game;
|
|
||||||
import org.justcheckers.game.Rulebook;
|
|
||||||
import org.testng.Assert;
|
|
||||||
import org.testng.annotations.BeforeClass;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the game state logic. Tests the NQPOJO (not quite plain old Java
|
|
||||||
* objects) that handle the state of a game. This includes the Rulebook
|
|
||||||
* (that dictate what rules will be used for a game), the Board (that represents
|
|
||||||
* the state of the board, pieces, etc.) and the Game itself.
|
|
||||||
*
|
|
||||||
* TestNG version: 5.10
|
|
||||||
*
|
|
||||||
* @author dorianpula
|
|
||||||
*/
|
|
||||||
public class GameStateTest {
|
|
||||||
|
|
||||||
/** A test game of checkers. */
|
|
||||||
private Game testGame;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up a rather plain game of checkers. Game is based on the American
|
|
||||||
* rules, to make life easier.
|
|
||||||
*/
|
|
||||||
@BeforeClass
|
|
||||||
public void setUp() {
|
|
||||||
this.testGame = new Game();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the rulebook of a default initialized game.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testDefaultRulebookSetup() {
|
|
||||||
Rulebook testRules = this.testGame.getGameRules();
|
|
||||||
|
|
||||||
Assert.assertNull(testRules);
|
|
||||||
|
|
||||||
//TODO: Test the ruleset that is gets initialized properly.
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Populate with test cases.
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
InternationalGameTest.java -- Regression test of a game played according to
|
|
||||||
International rules.
|
|
||||||
*****************************************************************************
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
This file is part of justCheckers.
|
|
||||||
|
|
||||||
justCheckers is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
justCheckers is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
package org.justcheckers.test.game;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Regression test for a game of checkers played according to International
|
|
||||||
* rules.
|
|
||||||
* International rules are:
|
|
||||||
* - 10x10 board.
|
|
||||||
* - Pawns can move 1 space forward.
|
|
||||||
* - Kings can move 1 space forward. But can capture backwards.
|
|
||||||
* - The game ends when one player is eliminated or completely blocked.
|
|
||||||
*
|
|
||||||
* TestNG version: 5.10
|
|
||||||
*
|
|
||||||
* @author Dorian Pula
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InternationalGameTest {
|
|
||||||
//TODO: Populate with test cases.
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
Gradle Build for justCheckers - Desktop
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers-desktop'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
// TODO Add in build for the desktop client.
|
|
|
@ -0,0 +1 @@
|
||||||
|
__version__ = '0.3.0'
|
|
@ -0,0 +1,59 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PySide import QtGui
|
||||||
|
|
||||||
|
import justcheckers
|
||||||
|
from justcheckers.ui.window import DesktopGameWindow
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main entry point into the app."""
|
||||||
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
log_system_and_game_info()
|
||||||
|
view = DesktopGameWindow()
|
||||||
|
view.show()
|
||||||
|
app.exec_()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def log_system_and_game_info():
|
||||||
|
"""Logs information about the game and system running the game."""
|
||||||
|
LOG.info('justCheckers -- v{}'.format(justcheckers.__version__))
|
||||||
|
|
||||||
|
message = 'I am running on {os}.\nMy screen is {height}x{width}'
|
||||||
|
geometry = QtGui.QDesktopWidget().availableGeometry()
|
||||||
|
|
||||||
|
os_sys = sys.platform
|
||||||
|
if sys.platform == 'posix':
|
||||||
|
os_name, _, _, _, os_arch = os.uname()
|
||||||
|
os_sys = '{name} {arch}'.format(name=os_name, arch=os_arch)
|
||||||
|
|
||||||
|
LOG.info(message.format(os=os_sys, height=geometry.height(), width=geometry.width()))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,62 @@
|
||||||
|
What is justCheckers?
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
justCheckers is an advanced libre source checkers game. The project's aim is to create a checkers game that:
|
||||||
|
|
||||||
|
* handles skins and themes
|
||||||
|
* handles multimedia
|
||||||
|
* allows for network games
|
||||||
|
* contains a powerful yet fun computer opponent
|
||||||
|
* simplifies managing on-line checkers tournaments
|
||||||
|
* handles different checker rules
|
||||||
|
|
||||||
|
This project is powered by Python 2 + PySide (Qt 4)
|
||||||
|
|
||||||
|
[justCheckers homepage - http://justcheckers.org/](http://justcheckers.org/)
|
||||||
|
|
||||||
|
Developers
|
||||||
|
==========
|
||||||
|
|
||||||
|
Current
|
||||||
|
-------
|
||||||
|
|
||||||
|
**Dorian Pula**
|
||||||
|
|
||||||
|
- Founder, lead developer, project management, documentation & core programming.
|
||||||
|
|
||||||
|
Past
|
||||||
|
----
|
||||||
|
|
||||||
|
**Chris Bellini**
|
||||||
|
|
||||||
|
- Game engine data objects, XML settings & project management.
|
||||||
|
- Versions 0.0-0.1
|
||||||
|
|
||||||
|
**Daniel D'Alimonte (skwirl)**
|
||||||
|
|
||||||
|
- Code clean-up, refactoring, documentation & file releases.
|
||||||
|
- Inspiration for move to PySide
|
||||||
|
- Versions 0.0-0.1
|
||||||
|
|
||||||
|
**Ross Etchells**
|
||||||
|
|
||||||
|
- Game engine logic and progressing.
|
||||||
|
- Versions 0.0-0.1
|
||||||
|
|
||||||
|
**Rras Lekone**
|
||||||
|
|
||||||
|
- Console UI (jCurses)
|
||||||
|
- Versions 0.0
|
||||||
|
|
||||||
|
**Brinick Simmons**
|
||||||
|
|
||||||
|
- Core programming, XML settings and processing.
|
||||||
|
- Versions 0.0-0.1
|
||||||
|
|
||||||
|
Special Thanks
|
||||||
|
--------------
|
||||||
|
|
||||||
|
**Nick Nolfi**
|
||||||
|
|
||||||
|
- Creator of the Chubby Checkers project and assignment.
|
||||||
|
- Inspiration for Civilization Checkers and justCheckers.
|
|
@ -0,0 +1,355 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from justcheckers.game import rules
|
||||||
|
|
||||||
|
|
||||||
|
class Square(Enum):
|
||||||
|
"""Represents the state of a single square on a checkerboard."""
|
||||||
|
WHITE = -1
|
||||||
|
EMPTY = 0
|
||||||
|
LIGHT_PAWN = 1
|
||||||
|
LIGHT_KING = 2
|
||||||
|
DARK_PAWN = 3
|
||||||
|
DARK_KING = 4
|
||||||
|
|
||||||
|
|
||||||
|
class Board(object):
|
||||||
|
"""
|
||||||
|
* Container for the state of the checker board during a game.
|
||||||
|
*
|
||||||
|
* The size of the board is defined by the number of squares along one side,
|
||||||
|
* since all checker boards are square. The board coordinate system has both
|
||||||
|
* horizontal and vertical numeric components ranging from 0 to boardSize-1.
|
||||||
|
* Depicted on-screen, the horizontal component extends to the right and the
|
||||||
|
* vertical component extends downwards, making the upper left square (0, 0) and
|
||||||
|
* the lower right square (boardSize-1, boardSize-1).
|
||||||
|
*
|
||||||
|
* <b>Navigating through the Board</b> Internally, the checker board is
|
||||||
|
* organized as a two-dimensional array. So when iterating through the board,
|
||||||
|
* you first specify the vertical component and then the horizontal component.
|
||||||
|
* Another way of thinking about is first specifying which row you want to look
|
||||||
|
* at from top to bottom. Then you specify how across the row you are looking at
|
||||||
|
* from left to right.
|
||||||
|
*
|
||||||
|
* <b>Players Places</b> The light player (the starting player) starts at the
|
||||||
|
* top of the board. The dark player starts at the bottom of the board.
|
||||||
|
*
|
||||||
|
* @author Dorian Pula
|
||||||
|
* @author Ross Etchells
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, size=rules.Rules.STANDARD_BOARD_SIZE, mirrored=False):
|
||||||
|
self.board_size = size
|
||||||
|
self._board = [[Square.EMPTY for y in xrange(0, self.board_size)] for x in xrange(0, self.board_size)]
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Clears the board of pieces. Creates a brand new empty board already laid
|
||||||
|
# * out by the rules (regular or mirrored).
|
||||||
|
# */
|
||||||
|
for row in xrange(0, size):
|
||||||
|
for col in xrange(0, size):
|
||||||
|
|
||||||
|
# Mirrored has opposite setup to a regular board.
|
||||||
|
if (row % 2 == 0) and (col % 2 == 0):
|
||||||
|
if mirrored:
|
||||||
|
self._board[row][col] = Square.WHITE
|
||||||
|
else:
|
||||||
|
self._board[row][col] = Square.EMPTY
|
||||||
|
|
||||||
|
elif (row % 2 == 0) and (col % 2 == 1):
|
||||||
|
if mirrored:
|
||||||
|
self._board[row][col] = Square.EMPTY
|
||||||
|
else:
|
||||||
|
self._board[row][col] = Square.WHITE
|
||||||
|
|
||||||
|
elif (row % 2 == 1) and (col % 2 == 0):
|
||||||
|
if mirrored:
|
||||||
|
self._board[row][col] = Square.EMPTY
|
||||||
|
else:
|
||||||
|
self._board[row][col] = Square.WHITE
|
||||||
|
else:
|
||||||
|
if mirrored:
|
||||||
|
self._board[row][col] = Square.WHITE
|
||||||
|
else:
|
||||||
|
self._board[row][col] = Square.EMPTY
|
||||||
|
|
||||||
|
def is_inside_board(self, row, col):
|
||||||
|
return (0 <= row < self.board_size) and (0 <= col < self.board_size)
|
||||||
|
|
||||||
|
def is_dark(self, row, col):
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Determines whether the piece at board coordinate (row, col) is dark. If
|
||||||
|
* the coordinates do not exist on the board or are empty, this method will
|
||||||
|
* return false.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* The row of the square.
|
||||||
|
* @param col
|
||||||
|
* The column of the square.
|
||||||
|
* @return True if the piece at the specified coordinate is dark. False if
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
"""
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.DARK_KING, Square.DARK_PAWN]
|
||||||
|
|
||||||
|
def is_empty(self, row, col):
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Determines whether the piece at board coordinate (row, col) is empty. If
|
||||||
|
* the coordinates do not exist on the board or is illegal, this method will
|
||||||
|
* return False.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* The row of the square.
|
||||||
|
* @param col
|
||||||
|
* The column of the square.
|
||||||
|
* @return True if the piece at the specified coordinate is empty. False if
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
"""
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] == Square.EMPTY
|
||||||
|
|
||||||
|
def is_illegal_space(self, row, col):
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Determines whether the board coordinate (x, y) is used in the game. In
|
||||||
|
* most cases, all light spaces on the board will be considered illegal.
|
||||||
|
* Also, any coordinate which does not exist is also considered illegal.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* The row of the square.
|
||||||
|
* @param col
|
||||||
|
* The column of the square.
|
||||||
|
* @return True if the specified coordinate is nonexistent or unused in the
|
||||||
|
* current rules. False if otherwise.
|
||||||
|
*/
|
||||||
|
"""
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] == Square.WHITE
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Determines whether the piece at board coordinate (row, col) is a king. If
|
||||||
|
# * the coordinates do not exist on the board or are empty, this method will
|
||||||
|
# * return False.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row of the square.
|
||||||
|
# * @param col
|
||||||
|
# * The column of the square.
|
||||||
|
# * @return True if the piece at the specified coordinate is a king. False if
|
||||||
|
# * otherwise.
|
||||||
|
# */
|
||||||
|
def is_king(self, row, col):
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.DARK_KING]
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Returns if a position specified is legal. Returns true if the position is
|
||||||
|
# * on the board, and if the space is not an illegal white space. Returns
|
||||||
|
# * False otherwise.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row coordinate of the position.
|
||||||
|
# * @param col
|
||||||
|
# * The column coordinate of the position.
|
||||||
|
# * @return Returns true if the position is a legal playing position.
|
||||||
|
# */
|
||||||
|
def is_legal_position(self, row, col):
|
||||||
|
return self.is_inside_board(row, col) and not self.is_illegal_space(row, col)
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Determines whether the piece at board coordinate (row, col) is light. If
|
||||||
|
# * the coordinates do not exist on the board or are empty, this method will
|
||||||
|
# * return False.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row of the square.
|
||||||
|
# * @param col
|
||||||
|
# * The column of the square.
|
||||||
|
# * @return True if the piece at the specified coordinate is light. False if
|
||||||
|
# * otherwise.
|
||||||
|
# */
|
||||||
|
def is_light(self, row, col):
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.LIGHT_PAWN]
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Determines whether the piece at board coordinate (row, col) is a pawn. If
|
||||||
|
# * the coordinates do not exist on the board or are empty, this method will
|
||||||
|
# * return False.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row of the square.
|
||||||
|
# * @param col
|
||||||
|
# * The column of the square.
|
||||||
|
# * @return True if the piece at the specified coordinate is a pawn. False if
|
||||||
|
# * otherwise.
|
||||||
|
# */
|
||||||
|
def is_pawn(self, row, col):
|
||||||
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_PAWN, Square.DARK_PAWN]
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Moves a pieces from one location to another. This method should be called
|
||||||
|
# * from the Game using this Board. This method does not check for rule
|
||||||
|
# * validity but does check for illegal white spaces. Also checks that the
|
||||||
|
# * destination position is empty.
|
||||||
|
# *
|
||||||
|
# * @param sourceRow
|
||||||
|
# * The row from where the piece is moving from.
|
||||||
|
# * @param sourceCol
|
||||||
|
# * The column from where the piece is moving from.
|
||||||
|
# * @param targetRow
|
||||||
|
# * The row to where the piece is moving to.
|
||||||
|
# * @param targetCol
|
||||||
|
# * The column to where the piece is moving to.
|
||||||
|
# */
|
||||||
|
def move_piece(self, source_row, source_col, target_row, target_col):
|
||||||
|
|
||||||
|
if (self.is_legal_position(source_row, source_col)
|
||||||
|
and self.is_legal_position(target_row, target_col)
|
||||||
|
and self._board[target_row][target_col] == Square.EMPTY):
|
||||||
|
|
||||||
|
self._board[source_row][source_col], self._board[target_row][target_col] = (
|
||||||
|
Square.EMPTY, self._board[source_row][source_col])
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Removes a pieces from the specified location. This method should be
|
||||||
|
# * called from the Game using this Board. This method does not check for
|
||||||
|
# * rule validity but does check for illegal white spaces.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row where the piece is to be removed from.
|
||||||
|
# * @param col
|
||||||
|
# * The column where the piece is to be removed from.
|
||||||
|
# */
|
||||||
|
def remove_piece(self, row, col):
|
||||||
|
if self.is_legal_position(row, col):
|
||||||
|
self._board[row][col] = Square.EMPTY
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Setups the board for a new game. There are three different setups for the
|
||||||
|
# * three different types of boards:
|
||||||
|
# *
|
||||||
|
# * <table>
|
||||||
|
# * <tr>
|
||||||
|
# * <b>
|
||||||
|
# * <td>Name</td>
|
||||||
|
# * <td>Size</td>
|
||||||
|
# * <td>Number of Pieces Per Player</td>
|
||||||
|
# * <td>Number of Rows Per Player</td>
|
||||||
|
# * </b>
|
||||||
|
# * </tr>
|
||||||
|
# * <tr>
|
||||||
|
# * <td>Standard</td>
|
||||||
|
# * <td>8 x 8</td>
|
||||||
|
# * <td>12</td>
|
||||||
|
# * <td>3</td>
|
||||||
|
# * </tr>
|
||||||
|
# * <tr>
|
||||||
|
# * <td>International</td>
|
||||||
|
# * <td>10 x 10</td>
|
||||||
|
# * <td>20</td>
|
||||||
|
# * <td>4</td>
|
||||||
|
# * </tr>
|
||||||
|
# * <tr>
|
||||||
|
# * <td>Canadian</td>
|
||||||
|
# * <td>12 x 12</td>
|
||||||
|
# * <td>30</td>
|
||||||
|
# * <td>5</td>
|
||||||
|
# * </tr>
|
||||||
|
# * </table>
|
||||||
|
# *
|
||||||
|
# * The columns containing the players' tokens alternate between columns. The
|
||||||
|
# * dark player traditionally takes the first few upper rows (0-3). The light
|
||||||
|
# * player takes the last of the lower rows (5-7, 6-9 or 7-11).
|
||||||
|
# *
|
||||||
|
# * Note that the suicide checkers variant has a completely different setup,
|
||||||
|
# * and has a setup function of its own: setupNewSuicideGame().
|
||||||
|
# */
|
||||||
|
def setup_new_game(self):
|
||||||
|
|
||||||
|
# Used to decide which rows to fill up.
|
||||||
|
# Figure out the size of the board.
|
||||||
|
if self.board_size == rules.InternationalRules.INTERNATIONAL_BOARD_SIZE:
|
||||||
|
dark_player_bottom_row = 3
|
||||||
|
light_player_top_row = 6
|
||||||
|
elif self.board_size == rules.CanadianRules.CANADIAN_BOARD_SIZE:
|
||||||
|
dark_player_bottom_row = 3
|
||||||
|
light_player_top_row = 7
|
||||||
|
else:
|
||||||
|
# Default board is 8x8 Standard size.
|
||||||
|
dark_player_bottom_row = 2
|
||||||
|
light_player_top_row = 5
|
||||||
|
|
||||||
|
# Go through the board and set it up.
|
||||||
|
for row in xrange(0, self.board_size):
|
||||||
|
for col in xrange(0, self.board_size):
|
||||||
|
if row <= dark_player_bottom_row and self._board[row][col] == Square.EMPTY:
|
||||||
|
self._board[row][col] = Square.DARK_PAWN
|
||||||
|
elif row >= light_player_top_row and self._board[row][col] == Square.EMPTY:
|
||||||
|
self._board[row][col] = Square.LIGHT_PAWN
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Setups a checker board according to the suicide "French" rules.
|
||||||
|
# */
|
||||||
|
def setup_new_suicide_game(self):
|
||||||
|
# TODO: Implement the suicide game setup.
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""
|
||||||
|
Override __str__ to get back an elegant unicode representation of the board.
|
||||||
|
|
||||||
|
:returns: A text representation of the current state of the board.
|
||||||
|
"""
|
||||||
|
# TODO Fix up string building setup. Separate into smaller component functions.
|
||||||
|
|
||||||
|
# Prepare for output with a nice looking to banner.
|
||||||
|
output = " "
|
||||||
|
for row in xrange(0, self.board_size):
|
||||||
|
if row < 9:
|
||||||
|
output = '{} {} '.format(output, row + 1)
|
||||||
|
else:
|
||||||
|
output = '{} {}'.format(output, row + 1)
|
||||||
|
output = output + "\n\n"
|
||||||
|
|
||||||
|
output_atom = {
|
||||||
|
Square.WHITE: u"\u2588\u2588\u2588",
|
||||||
|
Square.EMPTY: u" ",
|
||||||
|
Square.LIGHT_PAWN: u" \u2659 ",
|
||||||
|
Square.LIGHT_KING: u" \u2654 ",
|
||||||
|
Square.DARK_PAWN: u" \u265F ",
|
||||||
|
Square.DARK_KING: u" \u265A ",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Go row by row, printing out the row number and the board's state.
|
||||||
|
for row in xrange(0, self.board_size):
|
||||||
|
if row < 9:
|
||||||
|
output = u'{}{} '.format(output, row + 1)
|
||||||
|
else:
|
||||||
|
output = u'{}{} '.format(output, row + 1)
|
||||||
|
|
||||||
|
# Get current row's state.
|
||||||
|
for col in xrange(0, self.board_size):
|
||||||
|
output = output + output_atom[self._board[row][col]]
|
||||||
|
|
||||||
|
output = output + "\n"
|
||||||
|
|
||||||
|
return output
|
|
@ -0,0 +1,76 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from justcheckers.game import rules
|
||||||
|
|
||||||
|
Point = namedtuple('Point', ['x', 'y'])
|
||||||
|
|
||||||
|
|
||||||
|
class GameState(Enum):
|
||||||
|
NOT_STARTED = 0
|
||||||
|
LIGHT_MOVE = 1
|
||||||
|
DARK_MOVE = 2
|
||||||
|
LIGHT_VICTORY = 3
|
||||||
|
DARK_VICTORY = 4
|
||||||
|
DRAW = 5
|
||||||
|
|
||||||
|
|
||||||
|
class Game(object):
|
||||||
|
"""
|
||||||
|
Handles the logic behind the main game loop.
|
||||||
|
|
||||||
|
:author: Ross Etchells
|
||||||
|
:author: Dorian Pula
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, light_player,
|
||||||
|
dark_player,
|
||||||
|
game_board=None,
|
||||||
|
game_rules=rules.CheckersVariant.American,
|
||||||
|
game_state=GameState.NOT_STARTED):
|
||||||
|
"""
|
||||||
|
Initializes a new checker game
|
||||||
|
|
||||||
|
:param light_player: The attack player.
|
||||||
|
:param dark_player: The defending player.
|
||||||
|
:param game_board: The checkerboard to use for the game.
|
||||||
|
:param game_rules: The set of rules to use.
|
||||||
|
:param game_state: The state of the game.
|
||||||
|
:return: A representation of the game board.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.light_player = light_player
|
||||||
|
self.dark_player = dark_player
|
||||||
|
self.board = game_board
|
||||||
|
|
||||||
|
# TODO Initialize the rulebooks
|
||||||
|
self.rules = game_rules
|
||||||
|
self.state = game_state
|
||||||
|
|
||||||
|
def is_light_player_turn(self):
|
||||||
|
"""
|
||||||
|
Gets if it is the light player's turn. Returns false if it is the dark player's turn.
|
||||||
|
|
||||||
|
:returns: True if it is the light player's turn. Returns false if it is the dark player's turn.
|
||||||
|
"""
|
||||||
|
return self.state in [GameState.LIGHT_MOVE, GameState.LIGHT_VICTORY]
|
|
@ -0,0 +1,256 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
def canJump(game, sourceRow, sourceCol, targetRow, targetCol):
|
||||||
|
# TODO: Implement me.
|
||||||
|
# TODO: Make as private method.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Returns if a piece can or cannot move. This move maybe either be a move
|
||||||
|
# * or a jump. This method is called by a user interface when a user wants to
|
||||||
|
# * moves a piece on screen or over the network. The piece can moved if the
|
||||||
|
# * current state of the game allows for it to do so.
|
||||||
|
# *
|
||||||
|
# * TODO: Add priority for king jumps over pawn jumps for any variants that
|
||||||
|
# * do so.
|
||||||
|
# *
|
||||||
|
# * @param sourceRow
|
||||||
|
# * The row from where the piece is moving from.
|
||||||
|
# * @param sourceCol
|
||||||
|
# * The column from where the piece is moving from.
|
||||||
|
# * @param targetRow
|
||||||
|
# * The row to where the piece is moving to.
|
||||||
|
# * @param targetCol
|
||||||
|
# * The column to where the piece is moving to.
|
||||||
|
# * @return True if the piece can move. False if the piece can not move.
|
||||||
|
# */
|
||||||
|
def canMove(game, sourceRow, sourceCol, targetRow, targetCol):
|
||||||
|
|
||||||
|
# // A few things to figure out priorities in moving a piece.
|
||||||
|
legalMove = False
|
||||||
|
# // Is the proposed move/jump legal?
|
||||||
|
realPositions = False
|
||||||
|
# // Are the positions really on the board?
|
||||||
|
isJump = False
|
||||||
|
# // Is this a jump?
|
||||||
|
|
||||||
|
# // Sanity check.
|
||||||
|
if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
|
||||||
|
and game.getGameBoard().isLegalPosition(targetRow, targetCol)):
|
||||||
|
realPositions = True
|
||||||
|
|
||||||
|
# // Is there a jump in progress?
|
||||||
|
if (realPositions and game.getJumpInProgress() != None):
|
||||||
|
|
||||||
|
# // Only allow the piece in movement to be moved.
|
||||||
|
if (sourceRow == game.getJumpInProgress().getY()
|
||||||
|
and sourceCol == game.getJumpInProgress().getX()):
|
||||||
|
legalMove = canJump(game, sourceRow, sourceCol, targetRow,
|
||||||
|
targetCol)
|
||||||
|
isJump = True
|
||||||
|
|
||||||
|
elif (realPositions):
|
||||||
|
|
||||||
|
# // Go with the regular flow, jumps first then "slides".
|
||||||
|
isJump = canPlayerJump(game)
|
||||||
|
if isJump:
|
||||||
|
legalMove = canJump(game, sourceRow, sourceCol, targetRow,
|
||||||
|
targetCol)
|
||||||
|
else:
|
||||||
|
legalMove = canSlide(game, sourceRow, sourceCol, targetRow,
|
||||||
|
targetCol)
|
||||||
|
|
||||||
|
return legalMove
|
||||||
|
|
||||||
|
def canPlayerJump(game):
|
||||||
|
# // TODO: Implement me.
|
||||||
|
# TODO Make as private method
|
||||||
|
return False
|
||||||
|
|
||||||
|
def canSlide(game, sourceRow, sourceCol, targetRow, targetCol):
|
||||||
|
|
||||||
|
# TODO Make private
|
||||||
|
legalMove = True
|
||||||
|
mustJump = canPlayerJump(game)
|
||||||
|
|
||||||
|
# // Is the move even on the board?
|
||||||
|
legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol)\
|
||||||
|
and game.getGameBoard().isLegalPosition(targetRow, targetCol)
|
||||||
|
|
||||||
|
# // See if the destination is even empty.
|
||||||
|
if (legalMove):
|
||||||
|
legalMove = game.getGameBoard().isEmpty(targetRow, targetCol)
|
||||||
|
|
||||||
|
# // If yes, then look if right pieces were chosen.
|
||||||
|
if (legalMove and not mustJump):
|
||||||
|
if (game.isLightPlayerTurn() and game.getGameBoard().isLight(sourceRow, sourceCol)):
|
||||||
|
|
||||||
|
# // To deal with flying kings.
|
||||||
|
if (game.getGameBoard().isKing(sourceRow, sourceCol)
|
||||||
|
and game.getGameRules().canKingsFly()):
|
||||||
|
|
||||||
|
# // FIXME: Fix this!
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# // if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) {
|
||||||
|
# // legalMove = false;
|
||||||
|
|
||||||
|
# // Is the path clear for that move?
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif (not game.isLightPlayerTurn() and game.getGameBoard().isDark(sourceRow, sourceCol)):
|
||||||
|
|
||||||
|
# //TODO: Implement me, sometime.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
legalMove = False
|
||||||
|
|
||||||
|
return legalMove;
|
||||||
|
|
||||||
|
|
||||||
|
def checkForVictory(game):
|
||||||
|
# // TODO: Implement me.
|
||||||
|
pass
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Gets if a piece is movable. Returns True if the piece can slide or jump.
|
||||||
|
# * This method only calculates slides to the adjacent positions. Similarly,
|
||||||
|
# * the method only looks at jumping an adjacent enemy piece. This check is
|
||||||
|
# * used by the graphical user interface to determine if a piece can be moved
|
||||||
|
# * either for sliding or jumping. The method is aware of whose turn is it to
|
||||||
|
# * move.
|
||||||
|
# *
|
||||||
|
# * @param row
|
||||||
|
# * The row coordinate of the piece to check.
|
||||||
|
# * @param col
|
||||||
|
# * The column coordinate of the piece to check.
|
||||||
|
# * @return Returns True if the piece can slide or jump in this turn.
|
||||||
|
# */
|
||||||
|
def isMovablePiece(game, row, col):
|
||||||
|
|
||||||
|
# // Fields for determining of a piece is movable.
|
||||||
|
moveUpLeft = True
|
||||||
|
moveUpRight = True
|
||||||
|
moveDownLeft = True
|
||||||
|
moveDownRight = True
|
||||||
|
|
||||||
|
# /*
|
||||||
|
# * Checks first if the first colour of piece is being grabbed. Next if
|
||||||
|
# * the piece is blocked by its own pieces. Next if the opponent has
|
||||||
|
# * double blocked off the pieces. Also sanity checks if looking past the
|
||||||
|
# * size of the board.
|
||||||
|
# */
|
||||||
|
if (game.isLightPlayerTurn() and game.getGameBoard().isLight(row, col)):
|
||||||
|
|
||||||
|
# // Light player.
|
||||||
|
|
||||||
|
# // Can piece move normally?
|
||||||
|
moveDownLeft = canSlide(game, row, col, row + 1, col - 1)
|
||||||
|
moveDownRight = canSlide(game, row, col, row + 1, col + 1)
|
||||||
|
|
||||||
|
if (game.getGameBoard().isKing(row, col)):
|
||||||
|
moveUpLeft = canSlide(game, row, col, row - 1, col - 1)
|
||||||
|
moveUpRight = canSlide(game, row, col, row - 1, col + 1)
|
||||||
|
else:
|
||||||
|
moveUpLeft = False
|
||||||
|
moveUpRight = False
|
||||||
|
|
||||||
|
# // If no slides available try doing the same except for jumps.
|
||||||
|
if (not moveDownLeft):
|
||||||
|
moveDownLeft = canJump(game, row, col, row + 2, col - 2)
|
||||||
|
elif (not moveDownRight):
|
||||||
|
moveDownRight = canJump(game, row, col, row + 2, col + 2)
|
||||||
|
elif (game.getGameBoard().isKing(row, col)
|
||||||
|
or game.getGameRules().canPawnsJumpBackwards()):
|
||||||
|
|
||||||
|
if (not moveUpLeft):
|
||||||
|
moveUpLeft = canJump(game, row, col, row - 2, col + 2)
|
||||||
|
elif (not moveUpRight):
|
||||||
|
moveUpRight = canJump(game, row, col, row - 2, col - 2)
|
||||||
|
|
||||||
|
return moveUpLeft or moveUpRight or moveDownLeft or moveDownRight
|
||||||
|
|
||||||
|
elif (game.isLightPlayerTurn() and game.getGameBoard().isDark(row, col)):
|
||||||
|
# // Dark player
|
||||||
|
|
||||||
|
# // Can piece move normally?
|
||||||
|
moveUpLeft = canSlide(game, row, col, row - 1, col - 1)
|
||||||
|
moveUpRight = canSlide(game, row, col, row - 1, col + 1)
|
||||||
|
|
||||||
|
if (game.getGameBoard().isKing(row, col)):
|
||||||
|
moveDownLeft = canSlide(game, row, col, row + 1, col - 1)
|
||||||
|
moveDownRight = canSlide(game, row, col, row + 1, col + 1)
|
||||||
|
else:
|
||||||
|
moveDownLeft = False
|
||||||
|
moveDownRight = False
|
||||||
|
|
||||||
|
# // If no slides available try doing the same except for jumps.
|
||||||
|
if (not moveUpLeft):
|
||||||
|
moveUpLeft = canJump(game, row, col, row - 2, col - 2)
|
||||||
|
elif (not moveUpRight):
|
||||||
|
moveUpRight = canJump(game, row, col, row - 2, col + 2)
|
||||||
|
elif (game.getGameBoard().isKing(row, col)
|
||||||
|
or game.getGameRules().canPawnsJumpBackwards()):
|
||||||
|
|
||||||
|
if (not moveDownLeft):
|
||||||
|
moveDownLeft = canJump(game, row, col, row + 2, col + 2)
|
||||||
|
elif (not moveDownRight):
|
||||||
|
moveDownRight = canJump(game, row, col, row + 2, col - 2)
|
||||||
|
|
||||||
|
return moveUpLeft or moveUpRight or moveDownLeft or moveDownRight
|
||||||
|
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
# // A wrong coloured piece.
|
||||||
|
|
||||||
|
# /**
|
||||||
|
# * Moves a pieces from one location to another. This move maybe either be a
|
||||||
|
# * move or a jump. This method is called by a user interface when a user
|
||||||
|
# * moves a piece on screen or over the network. The piece is moved if the
|
||||||
|
# * current state of the game allows for it to do so.
|
||||||
|
# *
|
||||||
|
# * TODO: Add priority for king jumps over pawn jumps for any variants that
|
||||||
|
# * do so. TODO: Implement jumping by piece removal.
|
||||||
|
# *
|
||||||
|
# * @param sourceRow
|
||||||
|
# * The row from where the piece is moving from.
|
||||||
|
# * @param sourceCol
|
||||||
|
# * The column from where the piece is moving from.
|
||||||
|
# * @param targetRow
|
||||||
|
# * The row to where the piece is moving to.
|
||||||
|
# * @param targetCol
|
||||||
|
# * The column to where the piece is moving to.
|
||||||
|
# */
|
||||||
|
def movePiece(game, sourceRow, sourceCol, targetRow, targetCol):
|
||||||
|
|
||||||
|
# // If everything checks out... move the piecenot
|
||||||
|
if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)):
|
||||||
|
if (game.getJumpInProgress() != None):
|
||||||
|
|
||||||
|
# TODO: Implement jumping via removing of piece.
|
||||||
|
game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
|
||||||
|
targetCol)
|
||||||
|
else:
|
||||||
|
game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
|
||||||
|
targetCol)
|
||||||
|
|
||||||
|
checkForVictory(game)
|
|
@ -0,0 +1,41 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
class Player(object):
|
||||||
|
"""
|
||||||
|
Manages the information of a single player.
|
||||||
|
|
||||||
|
:author: Chris Bellini
|
||||||
|
:author: Dorian Pula
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name='Unnamed Player', wins=0, losses=0, ties=0):
|
||||||
|
self.name = name
|
||||||
|
self.wins = wins
|
||||||
|
self.losses = losses
|
||||||
|
self.ties = ties
|
||||||
|
|
||||||
|
def total_games_played(self):
|
||||||
|
return self.wins + self.losses + self.ties
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'Name: {name} \n Games: Won {wins} \ Lost {losses} \ Tied {ties}'.format(
|
||||||
|
name=self.name, wins=self.wins, losses=self.losses, ties=self.ties
|
||||||
|
)
|
|
@ -0,0 +1,216 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class CheckersVariant(Enum):
|
||||||
|
AMERICAN = 0
|
||||||
|
INTERNATIONAL = 1
|
||||||
|
BRAZILIAN = 2
|
||||||
|
CANADIAN = 3
|
||||||
|
POOL = 4
|
||||||
|
SPANISH = 5
|
||||||
|
RUSSIAN = 6
|
||||||
|
ITALIAN = 7
|
||||||
|
SUICIDE = 8
|
||||||
|
GHANAIAN = 9
|
||||||
|
|
||||||
|
|
||||||
|
class Rules(object):
|
||||||
|
"""
|
||||||
|
Abstraction of the rules for a game of checkers.
|
||||||
|
|
||||||
|
The rules for a game of checkers. This class provides a reference object for
|
||||||
|
a game of checkers. This helps deal with the number of variants of checkers.
|
||||||
|
One of the goals of justCheckers is to provide the flexibility of choose
|
||||||
|
between different kinds of checker variants. This class builds a skeleton of
|
||||||
|
the rules by defining what setup, moves, jumps, victory conditions and
|
||||||
|
special moves make up a particular variant of checkers.
|
||||||
|
|
||||||
|
:author: Dorian Pula
|
||||||
|
:author: Chris Bellini
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Victory conditions.
|
||||||
|
# Victory achieved by capturing all enemy pieces. */
|
||||||
|
CAPTURE_ALL_ENEMIES_VICTORY = 0
|
||||||
|
|
||||||
|
# TODO: Implement special rules for these checkers. Version >0.3?
|
||||||
|
# Victory achieved by capturing all pieces. Only caveat is the three king
|
||||||
|
# * versus one king draw rule:
|
||||||
|
# *
|
||||||
|
# * In many games at the end one adversary has three kings while the other
|
||||||
|
# * one has just one king. In such a case the first adversary must win in
|
||||||
|
# * thirteen moves or the game is declared a draw. (Shamelessly stolen from
|
||||||
|
# * http://en.wikipedia.org/wiki/Draughts).
|
||||||
|
# */
|
||||||
|
SPECIAL_POOL_VICTORY = 1
|
||||||
|
# Victory achieved some bizarre manner. TODO: Figure out Russian checkers.
|
||||||
|
SPECIAL_RUSSIAN_VICTORY = 2
|
||||||
|
# Victory achieved by losing all your pieces.
|
||||||
|
SPECIAL_SUICIDE_VICTORY = 3
|
||||||
|
# Victory achieved by not being the first with one piece left.
|
||||||
|
SPECIAL_GHANAIAN_VICTORY = 4
|
||||||
|
|
||||||
|
# TODO Move out into individual implementing Rules.
|
||||||
|
# Checker board sizes.
|
||||||
|
# Using a "standard" American checkers board.
|
||||||
|
STANDARD_BOARD_SIZE = 8
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
variant,
|
||||||
|
board_size=STANDARD_BOARD_SIZE,
|
||||||
|
kings_jump_multiple_times=True,
|
||||||
|
pawns_jump_backward=True,
|
||||||
|
light_player_starts_first=True,
|
||||||
|
mirrored_board=False,
|
||||||
|
force_capture=True,
|
||||||
|
force_capture_maximum=True):
|
||||||
|
|
||||||
|
self.checkers_variant = variant
|
||||||
|
self.board_size = board_size
|
||||||
|
|
||||||
|
self.can_kings_jump_multiple_times = kings_jump_multiple_times
|
||||||
|
self.can_pawns_jump_backwards = pawns_jump_backward
|
||||||
|
|
||||||
|
self.does_light_player_start_first = light_player_starts_first
|
||||||
|
self.is_board_mirrored = mirrored_board
|
||||||
|
self.is_player_forced_to_capture = force_capture
|
||||||
|
self.is_player_forced_to_capture_maximum_possible = force_capture_maximum
|
||||||
|
|
||||||
|
def is_player_victorious(self, player, game):
|
||||||
|
# TODO Check if the player is victorious
|
||||||
|
# TODO Implement me for the standard capture or block all opponent pieces.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class AmericanRules(Rules):
|
||||||
|
def __init__(self):
|
||||||
|
super(AmericanRules, self).__init__(
|
||||||
|
variant=CheckersVariant.AMERICAN,
|
||||||
|
kings_jump_multiple_times=False,
|
||||||
|
pawns_jump_backward=False,
|
||||||
|
light_player_starts_first=False,
|
||||||
|
force_capture_maximum=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InternationalRules(Rules):
|
||||||
|
INTERNATIONAL_BOARD_SIZE = 10
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(InternationalRules, self).__init__(
|
||||||
|
variant=CheckersVariant.INTERNATIONAL,
|
||||||
|
board_size=self.INTERNATIONAL_BOARD_SIZE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BrazilianRules(Rules):
|
||||||
|
def __init__(self):
|
||||||
|
super(BrazilianRules, self).__init__(
|
||||||
|
variant=CheckersVariant.BRAZILIAN,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CanadianRules(Rules):
|
||||||
|
CANADIAN_BOARD_SIZE = 12
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(CanadianRules, self).__init__(
|
||||||
|
variant=CheckersVariant.CANADIAN,
|
||||||
|
board_size=self.CANADIAN_BOARD_SIZE,
|
||||||
|
force_capture_maximum=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PoolRules(Rules):
|
||||||
|
def __init__(self):
|
||||||
|
super(PoolRules, self).__init__(
|
||||||
|
variant=CheckersVariant.POOL,
|
||||||
|
light_player_starts_first=False,
|
||||||
|
force_capture_maximum=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_player_victorious(self, player, game):
|
||||||
|
# TODO Check if the player is victorious
|
||||||
|
# TODO Implement special rules for Pool checkers.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class SpanishRules(Rules):
|
||||||
|
def __init__(self):
|
||||||
|
super(SpanishRules, self).__init__(
|
||||||
|
variant=CheckersVariant.SPANISH,
|
||||||
|
pawns_jump_backward=False,
|
||||||
|
mirrored_board=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RussianRules(Rules):
|
||||||
|
# TODO: Needs special freshly-kinged-but-still-can-jump special rule.
|
||||||
|
def __init__(self):
|
||||||
|
super(RussianRules, self).__init__(
|
||||||
|
variant=CheckersVariant.RUSSIAN,
|
||||||
|
force_capture_maximum=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_player_victorious(self, player, game):
|
||||||
|
# TODO Check if the player is victorious
|
||||||
|
# TODO Implement special rules for Russian checkers.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class ItalianRules(Rules):
|
||||||
|
def __init__(self):
|
||||||
|
super(ItalianRules, self).__init__(
|
||||||
|
variant=CheckersVariant.ITALIAN,
|
||||||
|
pawns_jump_backward=False,
|
||||||
|
mirrored_board=True,
|
||||||
|
)
|
||||||
|
# TODO: Special rule on must jump most number of kings per capture.
|
||||||
|
# TODO: Special rule that pawns can't capture kings.
|
||||||
|
|
||||||
|
|
||||||
|
class SuicideRules(Rules):
|
||||||
|
# TODO: Needs unconventional setup.
|
||||||
|
def __init__(self):
|
||||||
|
super(SuicideRules, self).__init__(
|
||||||
|
variant=CheckersVariant.SUICIDE,
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_player_victorious(self, player, game):
|
||||||
|
# TODO Check if the player is victorious
|
||||||
|
# TODO Implement special rules for suicide checkers.
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class GhanaianRules(Rules):
|
||||||
|
# TODO: Special forfeit king if passing up a king's capture opportunity.
|
||||||
|
def __init__(self):
|
||||||
|
super(GhanaianRules, self).__init__(
|
||||||
|
variant=CheckersVariant.GHANAIAN,
|
||||||
|
mirrored_board=True,
|
||||||
|
force_capture_maximum=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_player_victorious(self, player, game):
|
||||||
|
# TODO Check if the player is victorious
|
||||||
|
# TODO Implement special rules for Ghanian checkers.
|
||||||
|
return False
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
@ -0,0 +1,167 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
from PySide import QtGui
|
||||||
|
from PySide import QtCore
|
||||||
|
|
||||||
|
from justcheckers.game import board
|
||||||
|
from justcheckers.game.rules import Rules
|
||||||
|
|
||||||
|
|
||||||
|
Coordinates = namedtuple('Coordinates', ['x', 'y'])
|
||||||
|
|
||||||
|
|
||||||
|
class BoardSquare(QtGui.QGraphicsItem):
|
||||||
|
"""A single graphical unit that makes up the checkerboard."""
|
||||||
|
|
||||||
|
def __init__(self, coordinates, game_board, parent=None):
|
||||||
|
"""
|
||||||
|
Create a board square.
|
||||||
|
|
||||||
|
:param coordinates: A tuple with the row and column of board.
|
||||||
|
:param game_board: A reference to the game board to display the current state of the game.
|
||||||
|
:param parent: The parent widget for this graphical item.
|
||||||
|
:return: A graphical item representing a specific square on a checkerboard.
|
||||||
|
"""
|
||||||
|
super(BoardSquare, self).__init__(parent)
|
||||||
|
|
||||||
|
# TODO Add validation that coordinates match a real active game.
|
||||||
|
self.coordinates = coordinates
|
||||||
|
self.game_board = game_board
|
||||||
|
|
||||||
|
def boundingRect(self):
|
||||||
|
return QtCore.QRectF(-15, -50, 30, 50)
|
||||||
|
|
||||||
|
def paint(self, painter, option, widget=None):
|
||||||
|
|
||||||
|
# Draw the board
|
||||||
|
self.color = QtGui.QColor(QtCore.Qt.black)
|
||||||
|
if self.game_board.is_illegal_space(self.coordinates.x, self.coordinates.y):
|
||||||
|
self.color = QtGui.QColor(QtCore.Qt.white)
|
||||||
|
|
||||||
|
painter.setBrush(self.color)
|
||||||
|
painter.drawRect(0, 0, 50, 50)
|
||||||
|
|
||||||
|
# Draw the underlying piece.
|
||||||
|
if (self.game_board.is_empty(self.coordinates.x, self.coordinates.y)
|
||||||
|
or self.game_board.is_illegal_space(self.coordinates.x, self.coordinates.y)):
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO Add in a phantom outline of piece when dragging and dropping between board spaces
|
||||||
|
self.token_colour = QtGui.QColor(QtCore.Qt.darkGray)
|
||||||
|
if self.game_board.is_light(self.coordinates.x, self.coordinates.y):
|
||||||
|
self.token_colour = QtGui.QColor(QtCore.Qt.white)
|
||||||
|
|
||||||
|
painter.setPen(QtGui.QPen(QtCore.Qt.darkYellow, 2))
|
||||||
|
painter.setBrush(self.token_colour)
|
||||||
|
painter.drawEllipse(5, 5, 40, 40)
|
||||||
|
if self.game_board.is_king(self.coordinates.x, self.coordinates.y):
|
||||||
|
painter.drawText(15, 15, 'King')
|
||||||
|
|
||||||
|
|
||||||
|
class BoardBackground(QtGui.QGraphicsItem):
|
||||||
|
"""A graphical unit for the background of the checkerboard."""
|
||||||
|
|
||||||
|
def __init__(self, board_size=Rules.STANDARD_BOARD_SIZE, parent=None):
|
||||||
|
"""
|
||||||
|
Create a board square.
|
||||||
|
|
||||||
|
:param board_size: The size of the board in terms of rows or columns.
|
||||||
|
:param parent: The parent widget for this graphical item.
|
||||||
|
:return: A graphical item representing the background of a checkerboard.
|
||||||
|
"""
|
||||||
|
super(BoardBackground, self).__init__(parent)
|
||||||
|
self.board_size = board_size
|
||||||
|
|
||||||
|
def boundingRect(self):
|
||||||
|
return QtCore.QRectF(-15, -50, 30, 50)
|
||||||
|
|
||||||
|
def paint(self, painter, option, widget=None):
|
||||||
|
pixel_dimensions = 55 * self.board_size
|
||||||
|
painter.setPen(QtGui.QPen(QtCore.Qt.black, 2))
|
||||||
|
|
||||||
|
# FFC200
|
||||||
|
painter.setBrush(QtGui.QColor(255, 194, 0))
|
||||||
|
painter.drawRoundedRect(
|
||||||
|
-1 * pixel_dimensions,
|
||||||
|
-1 * pixel_dimensions,
|
||||||
|
pixel_dimensions + 10,
|
||||||
|
pixel_dimensions + 10,
|
||||||
|
10, 10, QtCore.Qt.RelativeSize)
|
||||||
|
|
||||||
|
|
||||||
|
class GameBoardWidget(QtGui.QGraphicsView):
|
||||||
|
|
||||||
|
def __init__(self, scene):
|
||||||
|
super(GameBoardWidget, self).__init__(scene)
|
||||||
|
self.scene = scene
|
||||||
|
|
||||||
|
def create_checker_board(self):
|
||||||
|
# TODO Cleaner implementation of passing in game board.
|
||||||
|
game_board = board.Board()
|
||||||
|
game_board.setup_new_game()
|
||||||
|
|
||||||
|
board_background = BoardBackground()
|
||||||
|
self.scene.addItem(board_background)
|
||||||
|
|
||||||
|
for row in xrange(8):
|
||||||
|
for column in xrange(8):
|
||||||
|
board_coords = Coordinates(x=column, y=row)
|
||||||
|
current_coords = Coordinates(x=55 * board_coords.x, y=55 * board_coords.y)
|
||||||
|
item = BoardSquare(board_coords, game_board, parent=board_background)
|
||||||
|
item.setPos(-1 * current_coords.x, -1 * current_coords.y)
|
||||||
|
|
||||||
|
# TODO Add in number of captured pieces and whose turn it is.
|
||||||
|
|
||||||
|
|
||||||
|
class GameView(QtGui.QWidget):
|
||||||
|
"""Game viewer for the game's license, etc."""
|
||||||
|
|
||||||
|
# TODO Setup functional testing with PySide.QtTest
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(GameView, self).__init__()
|
||||||
|
self.spaces_moved = 0
|
||||||
|
self.setup_components()
|
||||||
|
|
||||||
|
def setup_components(self):
|
||||||
|
self.game_board_scene = QtGui.QGraphicsScene()
|
||||||
|
self.game_board_widget = GameBoardWidget(self.game_board_scene)
|
||||||
|
|
||||||
|
self.game_board_widget.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(QtCore.Qt.green)))
|
||||||
|
self.game_board_widget.create_checker_board()
|
||||||
|
|
||||||
|
exit_button = QtGui.QPushButton('Back to Menu', self)
|
||||||
|
exit_button.setFixedHeight(50)
|
||||||
|
exit_button.clicked.connect(self.switch_to_menu_view)
|
||||||
|
|
||||||
|
widget_layout = QtGui.QVBoxLayout(self)
|
||||||
|
widget_layout.addWidget(self.game_board_widget)
|
||||||
|
|
||||||
|
button_row = QtGui.QHBoxLayout(self)
|
||||||
|
button_row.addWidget(exit_button)
|
||||||
|
|
||||||
|
widget_layout.addLayout(button_row)
|
||||||
|
|
||||||
|
self.setLayout(widget_layout)
|
||||||
|
|
||||||
|
def switch_to_menu_view(self):
|
||||||
|
self.parentWidget().setCurrentIndex(0)
|
|
@ -0,0 +1,84 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
import codecs
|
||||||
|
|
||||||
|
import markdown
|
||||||
|
from PySide import QtGui
|
||||||
|
from PySide import QtWebKit
|
||||||
|
|
||||||
|
from justcheckers.ui import util
|
||||||
|
|
||||||
|
|
||||||
|
class InfoView(QtGui.QWidget):
|
||||||
|
"""Info viewer for the game's license, etc."""
|
||||||
|
|
||||||
|
# TODO Setup functional testing with PySide.QtTest
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(InfoView, self).__init__()
|
||||||
|
self.setup_components()
|
||||||
|
|
||||||
|
def setup_components(self):
|
||||||
|
|
||||||
|
self.info_viewer = QtWebKit.QWebView(self)
|
||||||
|
about_html = self.generate_html_from_markdown('credits.md')
|
||||||
|
self.info_viewer.setHtml(about_html)
|
||||||
|
|
||||||
|
exit_button = QtGui.QPushButton('Back to Menu', self)
|
||||||
|
exit_button.setFixedHeight(50)
|
||||||
|
exit_button.clicked.connect(self.switch_to_menu_view)
|
||||||
|
|
||||||
|
credits_button = QtGui.QPushButton('Credits', self)
|
||||||
|
credits_button.setFixedHeight(50)
|
||||||
|
credits_button.clicked.connect(self.display_about_info)
|
||||||
|
|
||||||
|
license_button = QtGui.QPushButton('License', self)
|
||||||
|
license_button.setFixedHeight(50)
|
||||||
|
license_button.clicked.connect(self.display_license_info)
|
||||||
|
|
||||||
|
widget_layout = QtGui.QVBoxLayout(self)
|
||||||
|
widget_layout.addWidget(self.info_viewer)
|
||||||
|
|
||||||
|
button_row = QtGui.QHBoxLayout(self)
|
||||||
|
button_row.addWidget(exit_button)
|
||||||
|
button_row.addWidget(credits_button)
|
||||||
|
button_row.addWidget(license_button)
|
||||||
|
|
||||||
|
widget_layout.addLayout(button_row)
|
||||||
|
|
||||||
|
self.setLayout(widget_layout)
|
||||||
|
|
||||||
|
def switch_to_menu_view(self):
|
||||||
|
self.parentWidget().setCurrentIndex(0)
|
||||||
|
|
||||||
|
def display_about_info(self):
|
||||||
|
about_html = self.generate_html_from_markdown('credits.md')
|
||||||
|
self.info_viewer.setHtml(about_html)
|
||||||
|
|
||||||
|
def display_license_info(self):
|
||||||
|
license_html = self.generate_html_from_markdown('license.md')
|
||||||
|
self.info_viewer.setHtml(license_html)
|
||||||
|
|
||||||
|
def generate_html_from_markdown(self, filename):
|
||||||
|
file_path = util.path_to_asset(filename, asset_type=util.TEXT_ASSETS)
|
||||||
|
with codecs.open(file_path, mode='r', encoding='utf-8') as markdown_file:
|
||||||
|
text = markdown_file.read()
|
||||||
|
return markdown.markdown(text)
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
from PySide import QtCore
|
||||||
|
from PySide import QtGui
|
||||||
|
|
||||||
|
from justcheckers.ui import util
|
||||||
|
|
||||||
|
|
||||||
|
class MainMenuView(QtGui.QWidget):
|
||||||
|
"""Main menu for the game."""
|
||||||
|
|
||||||
|
# TODO Setup functional testing with PySide.QtTest
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(MainMenuView, self).__init__()
|
||||||
|
self.setup_components()
|
||||||
|
|
||||||
|
def setup_components(self):
|
||||||
|
"""Setup the components that make up the widget."""
|
||||||
|
self.init_justcheckers_logo()
|
||||||
|
|
||||||
|
self.new_game = self.create_menu_button('&New Game', enabled=True)
|
||||||
|
self.new_game.clicked.connect(self.switch_to_game_view)
|
||||||
|
|
||||||
|
self.open_game = self.create_menu_button('&Open Game')
|
||||||
|
self.save_game = self.create_menu_button('&Save Game')
|
||||||
|
|
||||||
|
self.about_game = self.create_menu_button('About Game', enabled=True)
|
||||||
|
self.about_game.clicked.connect(self.switch_to_about_view)
|
||||||
|
|
||||||
|
self.settings = self.create_menu_button('Settings')
|
||||||
|
|
||||||
|
self.exit_button = self.create_menu_button('Exit', enabled=True)
|
||||||
|
self.exit_button.clicked.connect(self.exit_app)
|
||||||
|
|
||||||
|
widget_layout = QtGui.QVBoxLayout(self)
|
||||||
|
widget_layout.addStretch()
|
||||||
|
widget_layout.addWidget(self.logo_label)
|
||||||
|
widget_layout.addStretch()
|
||||||
|
widget_layout.addWidget(self.new_game)
|
||||||
|
widget_layout.addWidget(self.open_game)
|
||||||
|
widget_layout.addWidget(self.save_game)
|
||||||
|
widget_layout.addWidget(self.about_game)
|
||||||
|
widget_layout.addWidget(self.settings)
|
||||||
|
widget_layout.addWidget(self.exit_button)
|
||||||
|
widget_layout.addStretch()
|
||||||
|
self.setLayout(widget_layout)
|
||||||
|
|
||||||
|
def init_justcheckers_logo(self):
|
||||||
|
"""Initializes and places the logo as a header on top of the menu."""
|
||||||
|
logo_pixmap = QtGui.QPixmap(util.path_to_asset('frosted_logo.png'))
|
||||||
|
view_size = self.size()
|
||||||
|
logo_pixmap = logo_pixmap.scaledToWidth(view_size.width())
|
||||||
|
|
||||||
|
self.logo_label = QtGui.QLabel('justCheckers', self)
|
||||||
|
self.logo_label.setPixmap(logo_pixmap)
|
||||||
|
self.logo_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
|
|
||||||
|
def create_menu_button(self, label, enabled=False):
|
||||||
|
"""Creates a menu button with a consistent look & feel."""
|
||||||
|
menu_button = QtGui.QPushButton(label, self)
|
||||||
|
menu_button.setFixedHeight(50)
|
||||||
|
menu_button.setEnabled(enabled)
|
||||||
|
return menu_button
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exit_app():
|
||||||
|
"""Exits the application."""
|
||||||
|
QtCore.QCoreApplication.instance().exit()
|
||||||
|
|
||||||
|
# TODO Remove magic numbers
|
||||||
|
def switch_to_about_view(self):
|
||||||
|
self.parentWidget().setCurrentIndex(1)
|
||||||
|
|
||||||
|
def switch_to_game_view(self):
|
||||||
|
self.parentWidget().setCurrentIndex(2)
|
|
@ -0,0 +1,15 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
IMAGE_ASSETS = 'images'
|
||||||
|
TEXT_ASSETS = 'assets'
|
||||||
|
|
||||||
|
|
||||||
|
def path_to_asset(filename, asset_type=IMAGE_ASSETS):
|
||||||
|
"""
|
||||||
|
Helper utility for getting the path to an asset.
|
||||||
|
|
||||||
|
:param filename: The filename of the asset.
|
||||||
|
:param asset_type: The type of asset. Defaults to images.
|
||||||
|
:return: The path to the asset.
|
||||||
|
"""
|
||||||
|
return os.path.join(os.path.dirname(__file__), os.pardir, asset_type.lower(), filename)
|
|
@ -0,0 +1,64 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||||
|
#
|
||||||
|
# justCheckers is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License,
|
||||||
|
# or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# justCheckers is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with justCheckers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Please share and enjoy!
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
from PySide import QtGui
|
||||||
|
|
||||||
|
from justcheckers.ui.game_view import GameView
|
||||||
|
from justcheckers.ui.info_view import InfoView
|
||||||
|
from justcheckers.ui.menu_view import MainMenuView
|
||||||
|
from justcheckers.ui import util
|
||||||
|
|
||||||
|
class DesktopGameWindow(QtGui.QMainWindow):
|
||||||
|
"""Main window for the game."""
|
||||||
|
# TODO Setup functional testing with PySide.QtTest
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(DesktopGameWindow, self).__init__()
|
||||||
|
self.setWindowTitle('justCheckers')
|
||||||
|
self.setGeometry(300, 300, 800, 600)
|
||||||
|
|
||||||
|
self.setWindowIcon(QtGui.QIcon(util.path_to_asset('icon.png')))
|
||||||
|
self.setup_components()
|
||||||
|
# self.add_backdrop() # TODO Add back with a nicer (animated?) backdrop
|
||||||
|
self.center()
|
||||||
|
|
||||||
|
def add_backdrop(self):
|
||||||
|
"""Adds a backdrop image to the game."""
|
||||||
|
tile = QtGui.QPixmap(util.path_to_asset('backdrop.jpg'))
|
||||||
|
palette = QtGui.QPalette()
|
||||||
|
palette.setBrush(QtGui.QPalette.Background, tile)
|
||||||
|
self.setPalette(palette)
|
||||||
|
|
||||||
|
def setup_components(self):
|
||||||
|
"""Setup the components that make up the widget."""
|
||||||
|
self.view_stack = QtGui.QStackedWidget()
|
||||||
|
self.view_stack.addWidget(MainMenuView())
|
||||||
|
self.view_stack.addWidget(InfoView())
|
||||||
|
self.view_stack.addWidget(GameView())
|
||||||
|
self.setCentralWidget(self.view_stack)
|
||||||
|
|
||||||
|
def center(self):
|
||||||
|
"""Centers the widget in the middle of the screen."""
|
||||||
|
widget_rectangle = self.frameGeometry()
|
||||||
|
center_point = QtGui.QDesktopWidget().availableGeometry().center()
|
||||||
|
widget_rectangle.moveCenter(center_point)
|
||||||
|
self.move(widget_rectangle.topLeft())
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Requirements for basic operation of the game.
|
||||||
|
|
||||||
|
# User interface
|
||||||
|
PySide==1.2.2
|
||||||
|
Markdown==2.4.1
|
||||||
|
PyOpenGL>=3.0.0
|
||||||
|
|
||||||
|
# Core logic
|
||||||
|
enum34==0.9.19
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Requirements for developing the justCheckers app
|
||||||
|
|
||||||
|
# Task management
|
||||||
|
invoke>=0.7.0
|
||||||
|
|
||||||
|
# Sphinx and Pygments
|
||||||
|
Sphinx>=1.2.2
|
||||||
|
# TODO Remove after the next release of releases.
|
||||||
|
-e git+https://github.com/bitprophet/releases@master#egg=releases
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
mock>=1.0.1
|
||||||
|
nose>=1.3.0
|
||||||
|
coverage>=3.6,<3.7
|
||||||
|
flake8>=2.1.0
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Requirements for the web front for justCheckers
|
||||||
|
Flask>=0.10
|
|
@ -1 +0,0 @@
|
||||||
include 'core', 'console', 'web', 'android', 'desktop'
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding=utf-8
|
||||||
|
import re
|
||||||
|
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
|
||||||
|
def gather_requirements(filename='requirements.txt'):
|
||||||
|
"""
|
||||||
|
Gather the requirements from a requirements file.
|
||||||
|
|
||||||
|
:param filename: The name of the file.
|
||||||
|
"""
|
||||||
|
with open(filename) as req_file:
|
||||||
|
raw_requirements = req_file.readlines()
|
||||||
|
|
||||||
|
return [requirement.strip()
|
||||||
|
for requirement in raw_requirements
|
||||||
|
if requirement.strip() and not re.match('#|-(?!e)', requirement)]
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='justcheckers',
|
||||||
|
version='0.5.0',
|
||||||
|
url='http://justcheckers.org/',
|
||||||
|
license='GPL v3',
|
||||||
|
author='Dorian Pula',
|
||||||
|
author_email='dorian.pula@gmail.com',
|
||||||
|
description='An advanced cross-platform checkers game.',
|
||||||
|
|
||||||
|
install_requires=gather_requirements(),
|
||||||
|
extras_requires={
|
||||||
|
'web': gather_requirements('requirements/web.txt'),
|
||||||
|
},
|
||||||
|
|
||||||
|
packages=find_packages(exclude=['tests']),
|
||||||
|
include_package_data=True,
|
||||||
|
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
'justcheckers = justcheckers.app:main',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Environment :: Console',
|
||||||
|
'Environment:: MacOS',
|
||||||
|
'Environment :: Web Environment',
|
||||||
|
'Environment :: Win32 (MS Windows)',
|
||||||
|
'Environment :: X11 Applications :: Qt',
|
||||||
|
'Intended Audience:: End Users / Desktop',
|
||||||
|
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||||
|
'Operating System :: MacOS :: MacOS X',
|
||||||
|
'Operating System :: Microsoft :: Windows',
|
||||||
|
'Operating System :: POSIX :: Linux',
|
||||||
|
'Operating System :: Unix',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3.3',
|
||||||
|
'Topic :: Games/Entertainment',
|
||||||
|
'Topic :: Games/Entertainment :: Board Games',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from invoke import task, run
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def clean():
|
||||||
|
"""Clean generated files."""
|
||||||
|
run('rm *.pyc')
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def docs():
|
||||||
|
"""Creates the HTML documentation through Sphinx."""
|
||||||
|
build_dirs = ['docs/_api', 'docs/_build']
|
||||||
|
for build_dir in build_dirs:
|
||||||
|
if not path.exists(build_dir):
|
||||||
|
os.mkdir(build_dir)
|
||||||
|
run('sphinx-apidoc -o docs/_api rookeries')
|
||||||
|
run('sphinx-build -b html docs docs/_build')
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def clean_docs():
|
||||||
|
"""Clean up the generated Sphinx documentation."""
|
||||||
|
sphinx_api_docs_dir = os.path.join(os.curdir, 'docs', '_api')
|
||||||
|
if os.path.exists(sphinx_api_docs_dir):
|
||||||
|
shutil.rmtree(sphinx_api_docs_dir)
|
||||||
|
|
||||||
|
sphinx_build_docs_dir = os.path.join(os.curdir, 'docs', '_build')
|
||||||
|
if os.path.exists(sphinx_build_docs_dir):
|
||||||
|
shutil.rmtree(sphinx_build_docs_dir)
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def test_style():
|
||||||
|
"""Test the coding style using Flake8."""
|
||||||
|
run('flake8')
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def test():
|
||||||
|
"""Test the webapp using both unit and integration nose tests."""
|
||||||
|
run('nosetests --with-coverage --cover-html --cover-package=justcheckers --cover-inclusive --cover-branches')
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def clean_tests():
|
||||||
|
"""Cleans test reports and artifacts."""
|
||||||
|
coverage_report_dir = os.path.join(os.curdir, 'cover')
|
||||||
|
if os.path.exists(coverage_report_dir):
|
||||||
|
shutil.rmtree(coverage_report_dir)
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def build_package():
|
||||||
|
"""Prepares the project for packaging."""
|
||||||
|
run('python setup.py sdist')
|
||||||
|
|
||||||
|
|
||||||
|
@task
|
||||||
|
def clean_package():
|
||||||
|
"""Cleans up generated files after packaging the project."""
|
||||||
|
packaging_dirs = [os.path.join(os.curdir, packaging) for packaging in ['justcheckers.egg-info', 'dist']]
|
||||||
|
for packaging in packaging_dirs:
|
||||||
|
if os.path.exists(packaging):
|
||||||
|
print("Removing '{}'".format(packaging))
|
||||||
|
shutil.rmtree(packaging)
|
|
@ -0,0 +1,2 @@
|
||||||
|
# TODO: Write full integration tests that mimic a full game of checkers of each variant.
|
||||||
|
# e.g. American, International, Polish...
|
132
web/build.gradle
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
Gradle Build for justCheckers - Web
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
Author: Dorian Pula (dorian.pula@amber-penguin-software.ca)
|
|
||||||
License: AGPL v3.
|
|
||||||
|
|
||||||
Gradle docs:
|
|
||||||
http://www.gradle.org/docs/current/userguide/userguide_single.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justCheckers'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
apply plugin: 'war'
|
|
||||||
apply plugin: 'jetty'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.6
|
|
||||||
targetCompatibility = 1.6
|
|
||||||
|
|
||||||
// Description of the project
|
|
||||||
description = 'justcheckers-web'
|
|
||||||
version = '0.3'
|
|
||||||
|
|
||||||
|
|
||||||
project.ext {
|
|
||||||
appName = 'justcheckers-web'
|
|
||||||
appBaseName = "justcheckers"
|
|
||||||
|
|
||||||
hibernateVersion = '3.5.4-Final'
|
|
||||||
slf4jVersion = '1.7.5'
|
|
||||||
springVersion = '3.1.3.RELEASE'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup build script repositories starting with Maven repositories
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url 'http://repo1.maven.org/maven2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dependency management
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
compile project(':core')
|
|
||||||
|
|
||||||
// Spring Framework + SLF4J
|
|
||||||
compile ('org.springframework:spring-context:' + project.springVersion) {
|
|
||||||
exclude module: 'commons-logging'
|
|
||||||
}
|
|
||||||
compile 'log4j:log4j:1.2.16'
|
|
||||||
compile 'org.slf4j:jcl-over-slf4j:' + project.slf4jVersion
|
|
||||||
compile 'org.slf4j:slf4j-api:' + project.slf4jVersion
|
|
||||||
compile 'org.slf4j:slf4j-log4j12:' + project.slf4jVersion
|
|
||||||
|
|
||||||
compile 'org.springframework:spring-jdbc:' + project.springVersion
|
|
||||||
compile 'org.springframework:spring-orm:' + project.springVersion
|
|
||||||
compile 'org.springframework:spring-webmvc:' + project.springVersion
|
|
||||||
compile 'org.springframework:spring-parent:' + project.springVersion
|
|
||||||
|
|
||||||
// xstream
|
|
||||||
compile 'com.thoughtworks.xstream:xstream:1.4.4'
|
|
||||||
|
|
||||||
// Hibernate + C3P0
|
|
||||||
compile 'org.hibernate:hibernate:' + project.hibernateVersion
|
|
||||||
compile 'org.hibernate:hibernate-annotations:' + project.hibernateVersion
|
|
||||||
compile 'org.hibernate:hibernate-c3p0:' + project.hibernateVersion
|
|
||||||
compile 'javassist:javassist:3.9.0.GA'
|
|
||||||
|
|
||||||
// FlexJson
|
|
||||||
compile 'net.sf.flexjson:flexjson:2.1'
|
|
||||||
|
|
||||||
// Javax Servlet and Mail APIs
|
|
||||||
providedCompile 'javax.servlet:servlet-api:2.5'
|
|
||||||
}
|
|
||||||
|
|
||||||
// At the end of day we just need a JAR and a WAR.
|
|
||||||
ext.sharedManifest = manifest {
|
|
||||||
|
|
||||||
attributes(
|
|
||||||
'App-Name' : project.appName,
|
|
||||||
'App-Version' : version,
|
|
||||||
'Build-User' : System.properties['user.name'],
|
|
||||||
'Build-Time' : new Date().format('yyyy-MMMM-dd HH:mm:ss'),
|
|
||||||
'Build-OS' : System.properties['os.name'] + ' - version ' + System.properties['os.version'],
|
|
||||||
'Build-Sys' : System.properties['os.arch'],
|
|
||||||
'Java-Version' : System.properties['java.version'],
|
|
||||||
'Java-Vendor' : System.properties['java.vendor'],
|
|
||||||
'Java-VM' :
|
|
||||||
System.properties['java.vm.vendor'] + ' ' + System.properties['java.vm.name'] + ' v'
|
|
||||||
+ System.properties['java.vm.version'])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the JAR.
|
|
||||||
jar {
|
|
||||||
enabled = true
|
|
||||||
includeEmptyDirs = false
|
|
||||||
manifest = sharedManifest
|
|
||||||
include '**/**.class'
|
|
||||||
exclude 'build/**'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build WAR files that include the JAR file. Add the resources back in.
|
|
||||||
war {
|
|
||||||
|
|
||||||
from 'webapp'
|
|
||||||
exclude 'WEB-INF/lib'
|
|
||||||
|
|
||||||
classpath = project.configurations.runtime - project.configurations.providedRuntime + jar.outputs.files
|
|
||||||
manifest = sharedManifest
|
|
||||||
|
|
||||||
includeEmptyDirs = false
|
|
||||||
into('WEB-INF/classes') {
|
|
||||||
from sourceSets.main.resources
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jettyRun {
|
|
||||||
httpPort = 8080
|
|
||||||
contextPath = project.appBaseName
|
|
||||||
webAppSourceDirectory = new File('webapp')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run embedded Jetty setup.
|
|
||||||
jettyRunWar {
|
|
||||||
httpPort = 8080
|
|
||||||
contextPath = project.appBaseName
|
|
||||||
}
|
|