Compare commits
65 Commits
master
...
rust-migra
Author | SHA1 | Date |
---|---|---|
Dorian | a60a9959b9 | |
Dorian | 3d1f6f4ec8 | |
Dorian | 4e695f3a7e | |
Dorian | 04d6837b5e | |
Dorian | c1608bacd1 | |
Dorian | 3af3ede5a7 | |
Dorian | 6b9027bdd8 | |
Dorian | fc9a706c90 | |
Dorian | 5e24c02cfb | |
Dorian | f20aa6989c | |
Dorian | c28458ff43 | |
Dorian | 3023f51e13 | |
Dorian | d152eb52d7 | |
Dorian | 2bb6ae818e | |
Dorian | a1e0c9ebb1 | |
Dorian | b33b6cf71c | |
Dorian | e1ca79c291 | |
Dorian | 2c6ec93484 | |
Dorian | 329152860d | |
Dorian | 7b36312ed3 | |
Dorian | 3f408edde6 | |
Dorian | 0e381b45ec | |
Dorian | 1a385d57bd | |
Dorian | c28457bbcf | |
Dorian | b6ff53fd8d | |
Dorian | c58c8b45fe | |
Dorian | b23d4a9460 | |
Dorian | 5f3e282afb | |
Dorian | f727ba7843 | |
Dorian | 81b17bef75 | |
Dorian | c6b39091ad | |
Dorian | c98a7d15d5 | |
Dorian | 0505a10045 | |
Dorian | 053430b77c | |
Dorian | a36a50464c | |
Dorian | eddfac271a | |
Dorian | ea9de695fd | |
Dorian | e5dae0520d | |
Dorian | 35742760b3 | |
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,83 @@
|
|||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
# Original kivy ignored
|
||||
bin
|
||||
.DS_Store
|
||||
.idea
|
||||
.gradle
|
||||
.eclipse
|
||||
.settings
|
||||
*.iml
|
||||
classes
|
||||
.buildozer
|
||||
|
||||
*.pyc
|
||||
docs/_build
|
||||
justcheckers.ini
|
||||
|
||||
/target
|
||||
**/*.rs.bk
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "orange"
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
# GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
## Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
@ -68,7 +68,8 @@ patents cannot be used to render the program non-free.
|
|||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
## TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "justcheckers-engine"
|
||||
version = "0.6.0"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[workspace]
|
||||
|
||||
members = [
|
||||
"engine",
|
||||
]
|
|
@ -0,0 +1,108 @@
|
|||
import QtQuick 2.0
|
||||
import QtMultimedia 5.8
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
Image {
|
||||
source: 'images/backdrop.jpg'
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: logo
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 20
|
||||
|
||||
color: Qt.rgba(1, 1, 1, 0.5)
|
||||
|
||||
width: parent.width
|
||||
height: logoImage.height
|
||||
|
||||
Image {
|
||||
id: logoImage
|
||||
source: 'images/logo.png'
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width
|
||||
spacing: 10
|
||||
|
||||
MenuButton {
|
||||
buttonText: "New Game"
|
||||
function actionOnClick() {
|
||||
appPage.source = "Board.qml"
|
||||
}
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
buttonText: "Open Game"
|
||||
enabled: false
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
buttonText: "Save Game"
|
||||
enabled: false
|
||||
function actionOnClick() {
|
||||
pingSound.seek(0)
|
||||
pingSound.play()
|
||||
}
|
||||
|
||||
// From: https://freesound.org/people/edsward/sounds/341871/
|
||||
Audio {
|
||||
id: pingSound
|
||||
source: 'assets/ping.wav'
|
||||
autoLoad: true
|
||||
}
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
buttonText: "About justCheckers"
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
buttonText: "Settings"
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 50
|
||||
height: parent.parent.height * 0.1
|
||||
text: "Quit"
|
||||
onPressed: Qt.quit()
|
||||
Material.accent: Material.Orange
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
buttonText: "Quit"
|
||||
function actionOnClick() {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 20
|
||||
|
||||
color: Qt.rgba(1, 1, 1, 0.5)
|
||||
width: parent.width
|
||||
height: 20
|
||||
|
||||
Text {
|
||||
text: "v" + appVersion
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 20
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Rectangle {
|
||||
id: button
|
||||
|
||||
property color backgroundAtRest: "#9e9e9e"
|
||||
property color backgroundActive: "#555555"
|
||||
property string buttonText: "Button"
|
||||
property bool enabled: true
|
||||
|
||||
function actionOnClick() { }
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
width: parent.width - 50
|
||||
height: parent.parent.height * 0.1
|
||||
radius: 10
|
||||
|
||||
color: {
|
||||
if (enabled)
|
||||
backgroundActive
|
||||
else
|
||||
backgroundAtRest
|
||||
}
|
||||
|
||||
border.color: "#333333"
|
||||
border.width: 2
|
||||
|
||||
antialiasing: true
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
horizontalOffset: 5
|
||||
verticalOffset: 5
|
||||
radius: 5.0
|
||||
samples: 5
|
||||
}
|
||||
|
||||
Text {
|
||||
text: buttonText
|
||||
font.pointSize: parent.height * 0.2
|
||||
font.bold: true
|
||||
height: 30
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: button.color = backgroundActive
|
||||
onReleased: button.color = backgroundAtRest
|
||||
onClicked: actionOnClick()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
[[source]]
|
||||
url = "https://pypi.python.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
invoke = "*"
|
||||
|
||||
[packages]
|
||||
Cython = "==0.23"
|
||||
PyInstaller = "*"
|
||||
|
||||
[packages.Kivy]
|
||||
git = "https://github.com/kivy/kivy"
|
||||
|
||||
[dev-packages.buildozer]
|
||||
git = "https://github.com/kivy/buildozer"
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "40e008e812036981170caeb7b5fe7df74140cee7b9afbf3c98d8d8569fa2260d"
|
||||
},
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"url": "https://pypi.python.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"Cython": {
|
||||
"hash": "sha256:7e23a6b242880ff95f5835c72e4e2a5bec42f801b0c18176d4379c05894007a6",
|
||||
"version": "==0.23"
|
||||
},
|
||||
"Kivy": {
|
||||
"git": "https://github.com/kivy/kivy"
|
||||
},
|
||||
"PyInstaller": {
|
||||
"hash": "sha256:f08ca806bc26e62034bca181a4b85de22568a3d39bdb062f05927c6e86c2a48c",
|
||||
"version": "==3.2.1"
|
||||
},
|
||||
"appdirs": {
|
||||
"hash": "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e",
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"packaging": {
|
||||
"hash": "sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388",
|
||||
"version": "==16.8"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hash": "sha256:fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010",
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hash": "sha256:33a7b7910651bea57164c6c6dd66a2b1c5196c0f78ee2ff7319ce7bd031714c0",
|
||||
"version": "==35.0.1"
|
||||
},
|
||||
"six": {
|
||||
"hash": "sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1",
|
||||
"version": "==1.10.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"buildozer": {
|
||||
"git": "https://github.com/kivy/buildozer"
|
||||
},
|
||||
"invoke": {
|
||||
"hash": "sha256:a1c825fcc213b6b1ee35a9483556bd8ade0ff549ac96132f58d679087cbfc57b",
|
||||
"version": "==0.16.3"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
# justCheckers
|
||||
|
||||
*justCheckers* is an advanced, cross-platform, libre source checkers game.
|
||||
The project's aim is to make a game capable of supporting:
|
||||
|
||||
- Skinning
|
||||
- Network Games
|
||||
- Computer Opponents
|
||||
- Various Rules and Internationalization
|
||||
- Multiple Desktop and Mobile OS
|
||||
|
||||
## Links
|
||||
|
||||
- [Website](http://justcheckers.dorianpula.ca/)
|
||||
- [Project Source](https://bitbucket.org/dorianpula/justcheckers/)
|
||||
- [Worlds Draughts Federation](https://fmjd.org/)
|
26
README.rst
|
@ -1,26 +0,0 @@
|
|||
======================
|
||||
justCheckers - README!
|
||||
======================
|
||||
|
||||
About the Project
|
||||
-----------------
|
||||
|
||||
*justCheckers* is an advanced open source checkers game for Android. The aim of
|
||||
the project is to make a game capable of supporting:
|
||||
|
||||
- Skinning
|
||||
- Network Games
|
||||
- Computer Opponents
|
||||
- Various Rules and Internationalizations
|
||||
- Cross platform (both OS and input types)
|
||||
|
||||
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
|
||||
-----
|
||||
|
||||
- Project website: http://justcheckers.org/
|
||||
- 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
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.
|
|
@ -0,0 +1,239 @@
|
|||
[app]
|
||||
|
||||
# (str) Title of your application
|
||||
title = justCheckers
|
||||
|
||||
# (str) Package name
|
||||
package.name = justcheckers
|
||||
|
||||
# (str) Package domain (needed for android/ios packaging)
|
||||
package.domain = org.justcheckers
|
||||
|
||||
# (str) Source code where the main.py live
|
||||
source.dir = .
|
||||
|
||||
# (list) Source files to include (let empty to include all the files)
|
||||
source.include_exts = py,png,jpg,kv,atlas,md
|
||||
|
||||
# (list) List of inclusions using pattern matching
|
||||
#source.include_patterns = assets/*,images/*.png
|
||||
|
||||
# (list) Source files to exclude (let empty to not exclude anything)
|
||||
#source.exclude_exts = spec
|
||||
|
||||
# (list) List of directory to exclude (let empty to not exclude anything)
|
||||
#source.exclude_dirs = tests, bin
|
||||
|
||||
# (list) List of exclusions using pattern matching
|
||||
#source.exclude_patterns = license,images/*/*.jpg
|
||||
|
||||
# (str) Application versioning (method 1)
|
||||
version = 0.3.0
|
||||
|
||||
# (str) Application versioning (method 2)
|
||||
# version.regex = __version__ = ['"](.*)['"]
|
||||
# version.filename = %(source.dir)s/main.py
|
||||
|
||||
# (list) Application requirements
|
||||
# comma seperated e.g. requirements = sqlite3,kivy
|
||||
requirements = kivy,hostpython2,docutils
|
||||
|
||||
# (str) Custom source folders for requirements
|
||||
# Sets custom source for any requirements with recipes
|
||||
# requirements.source.kivy = ../../kivy
|
||||
|
||||
# (list) Garden requirements
|
||||
#garden_requirements =
|
||||
|
||||
# (str) Presplash of the application
|
||||
presplash.filename = %(source.dir)s/images/splash.jpg
|
||||
|
||||
# (str) Icon of the application
|
||||
icon.filename = %(source.dir)s/images/icon.png
|
||||
|
||||
# (str) Supported orientation (one of landscape, portrait or all)
|
||||
orientation = landscape
|
||||
|
||||
# (list) List of service to declare
|
||||
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
|
||||
|
||||
#
|
||||
# OSX Specific
|
||||
#
|
||||
|
||||
#
|
||||
# author = © Copyright Info
|
||||
|
||||
#
|
||||
# Android specific
|
||||
#
|
||||
|
||||
# (bool) Indicate if the application should be fullscreen or not
|
||||
fullscreen = 1
|
||||
|
||||
# (list) Permissions
|
||||
android.permissions = INTERNET
|
||||
|
||||
# (int) Android API to use
|
||||
android.api = 19
|
||||
|
||||
# (int) Minimum API required
|
||||
android.minapi = 9
|
||||
|
||||
# (int) Android SDK version to use
|
||||
android.sdk = 20
|
||||
|
||||
# (str) Android NDK version to use
|
||||
android.ndk = 9c
|
||||
|
||||
# (bool) Use --private data storage (True) or --dir public storage (False)
|
||||
android.private_storage = True
|
||||
|
||||
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
|
||||
#android.ndk_path =
|
||||
|
||||
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
|
||||
#android.sdk_path =
|
||||
|
||||
# (str) ANT directory (if empty, it will be automatically downloaded.)
|
||||
#android.ant_path =
|
||||
|
||||
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
|
||||
#android.p4a_dir =
|
||||
|
||||
# (str) The directory in which python-for-android should look for your own build recipes (if any)
|
||||
#p4a.local_recipes =
|
||||
|
||||
# (str) Filename to the hook for p4a
|
||||
#p4a.hook =
|
||||
|
||||
# (list) python-for-android whitelist
|
||||
#android.p4a_whitelist =
|
||||
|
||||
# (bool) If True, then skip trying to update the Android sdk
|
||||
# This can be useful to avoid excess Internet downloads or save time
|
||||
# when an update is due and you just want to test/build your package
|
||||
# android.skip_update = False
|
||||
|
||||
# (str) Bootstrap to use for android builds (android_new only)
|
||||
# android.bootstrap = sdl2
|
||||
|
||||
# (str) Android entry point, default is ok for Kivy-based app
|
||||
#android.entrypoint = org.renpy.android.PythonActivity
|
||||
|
||||
# (list) List of Java .jar files to add to the libs so that pyjnius can access
|
||||
# their classes. Don't add jars that you do not need, since extra jars can slow
|
||||
# down the build process. Allows wildcards matching, for example:
|
||||
# OUYA-ODK/libs/*.jar
|
||||
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
|
||||
|
||||
# (list) List of Java files to add to the android project (can be java or a
|
||||
# directory containing the files)
|
||||
#android.add_src =
|
||||
|
||||
# (str) python-for-android branch to use, if not master, useful to try
|
||||
# not yet merged features.
|
||||
#android.branch = master
|
||||
|
||||
# (str) OUYA Console category. Should be one of GAME or APP
|
||||
# If you leave this blank, OUYA support will not be enabled
|
||||
#android.ouya.category = GAME
|
||||
|
||||
# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
|
||||
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
|
||||
|
||||
# (str) XML file to include as an intent filters in <activity> tag
|
||||
#android.manifest.intent_filters =
|
||||
|
||||
# (list) Android additionnal libraries to copy into libs/armeabi
|
||||
#android.add_libs_armeabi = libs/android/*.so
|
||||
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
|
||||
#android.add_libs_x86 = libs/android-x86/*.so
|
||||
#android.add_libs_mips = libs/android-mips/*.so
|
||||
|
||||
# (bool) Indicate whether the screen should stay on
|
||||
# Don't forget to add the WAKE_LOCK permission if you set this to True
|
||||
#android.wakelock = False
|
||||
|
||||
# (list) Android application meta-data to set (key=value format)
|
||||
#android.meta_data =
|
||||
|
||||
# (list) Android library project to add (will be added in the
|
||||
# project.properties automatically.)
|
||||
#android.library_references =
|
||||
|
||||
# (str) Android logcat filters to use
|
||||
#android.logcat_filters = *:S python:D
|
||||
|
||||
# (bool) Copy library instead of making a libpymodules.so
|
||||
#android.copy_libs = 1
|
||||
|
||||
# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86
|
||||
android.arch = armeabi-v7a
|
||||
|
||||
#
|
||||
# iOS specific
|
||||
#
|
||||
|
||||
# (str) Path to a custom kivy-ios folder
|
||||
#ios.kivy_ios_dir = ../kivy-ios
|
||||
|
||||
# (str) Name of the certificate to use for signing the debug version
|
||||
# Get a list of available identities: buildozer ios list_identities
|
||||
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
|
||||
|
||||
# (str) Name of the certificate to use for signing the release version
|
||||
#ios.codesign.release = %(ios.codesign.debug)s
|
||||
|
||||
|
||||
[buildozer]
|
||||
|
||||
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
|
||||
log_level = 2
|
||||
|
||||
# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
|
||||
warn_on_root = 1
|
||||
|
||||
# (str) Path to build artifact storage, absolute or relative to spec file
|
||||
# build_dir = ./.buildozer
|
||||
|
||||
# (str) Path to build output (i.e. .apk, .ipa) storage
|
||||
# bin_dir = ./bin
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# List as sections
|
||||
#
|
||||
# You can define all the "list" as [section:key].
|
||||
# Each line will be considered as a option to the list.
|
||||
# Let's take [app] / source.exclude_patterns.
|
||||
# Instead of doing:
|
||||
#
|
||||
#[app]
|
||||
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
|
||||
#
|
||||
# This can be translated into:
|
||||
#
|
||||
#[app:source.exclude_patterns]
|
||||
#license
|
||||
#data/audio/*.wav
|
||||
#data/images/original/*
|
||||
#
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Profiles
|
||||
#
|
||||
# You can extend section / key with a profile
|
||||
# For example, you want to deploy a demo version of your application without
|
||||
# HD content. You could first change the title to add "(demo)" in the name
|
||||
# and extend the excluded directories to remove the HD content.
|
||||
#
|
||||
#[app@demo]
|
||||
#title = My Application (demo)
|
||||
#
|
||||
#[app:source.exclude_patterns@demo]
|
||||
#images/hd/*
|
||||
#
|
||||
# Then, invoke the command line with the "demo" profile:
|
||||
#
|
||||
#buildozer --profile demo android debug
|
|
@ -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,7 @@
|
|||
[package]
|
||||
name = "justcheckers-engine"
|
||||
version = "0.6.0"
|
||||
authors = ["Dorian Pula <dorian.pula@amber-penguin-software.ca>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,201 @@
|
|||
use std::fmt;
|
||||
|
||||
pub enum Piece {
|
||||
LightPawn,
|
||||
LightKing,
|
||||
DarkPawn,
|
||||
DarkKing,
|
||||
}
|
||||
|
||||
pub enum BoardTile {
|
||||
Empty,
|
||||
Piece(Piece),
|
||||
}
|
||||
|
||||
pub enum BoardSize {
|
||||
American,
|
||||
International,
|
||||
Canadian,
|
||||
}
|
||||
|
||||
impl BoardSize {
|
||||
fn get_size(&self) -> usize {
|
||||
match &self {
|
||||
BoardSize::American => 8,
|
||||
BoardSize::International => 10,
|
||||
BoardSize::Canadian => 12,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Board {
|
||||
dimensions: BoardSize,
|
||||
tiles: Vec<BoardTile>,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
pub fn new(size: BoardSize) -> Board {
|
||||
let board_size = size.get_size();
|
||||
let width = board_size / 2;
|
||||
let height = board_size;
|
||||
let starting_rows = board_size / 2 - 1;
|
||||
|
||||
let playing_tiles = (0..width * height)
|
||||
.map(|tile| {
|
||||
let row = tile / width;
|
||||
match row {
|
||||
r if r < starting_rows => BoardTile::Piece(Piece::LightPawn),
|
||||
r if r > height - starting_rows - 1 => BoardTile::Piece(Piece::DarkPawn),
|
||||
_ => BoardTile::Empty,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
Board {
|
||||
dimensions: size,
|
||||
tiles: playing_tiles,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_index(&self, row: usize, column: usize) -> usize {
|
||||
let width = self.dimensions.get_size();
|
||||
(row * (width / 2) + column) as usize
|
||||
}
|
||||
}
|
||||
|
||||
static COLUMN_COORDINATE_BORDER: &str = " ABCDEFGHIJKL";
|
||||
|
||||
impl fmt::Display for Board {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let width = self.dimensions.get_size();
|
||||
|
||||
// Create the top level border.
|
||||
let (column_border_chars, _) = COLUMN_COORDINATE_BORDER.split_at(width + 1);
|
||||
writeln!(formatter, "{}", column_border_chars)?;
|
||||
|
||||
for row in 0..width {
|
||||
write!(formatter, "{}", (row + 1).to_string())?;
|
||||
|
||||
for col in 0..(width / 2) {
|
||||
let idx = self.get_index(row, col);
|
||||
let token = match &self.tiles[idx] {
|
||||
BoardTile::Piece(x) => match x {
|
||||
Piece::LightPawn => "○",
|
||||
Piece::LightKing => "⍟",
|
||||
Piece::DarkPawn => "●",
|
||||
Piece::DarkKing => "✪",
|
||||
},
|
||||
BoardTile::Empty => "◰",
|
||||
};
|
||||
|
||||
if row % 2 == 0 {
|
||||
write!(formatter, " {}", token)?;
|
||||
} else {
|
||||
write!(formatter, "{} ", token)?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(formatter, "\n")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub enum GameState {
|
||||
LightPlayerTurn,
|
||||
DarkPlayerTurn,
|
||||
LightPlayerWin,
|
||||
DarkPlayerWin,
|
||||
DrawGame,
|
||||
}
|
||||
|
||||
pub struct Game {
|
||||
board: Board,
|
||||
state: GameState,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
pub fn new(size: BoardSize) -> Game {
|
||||
// TODO: Add the concept of rulesets for the various checkers variants.
|
||||
Game {
|
||||
board: Board::new(size),
|
||||
state: GameState::LightPlayerTurn,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add in rules for long jump on kings, and forcing to jump as many pieces as possible.
|
||||
// TODO: only support the minimal setup required for an American game of checkers.
|
||||
|
||||
pub fn can_piece_move(&self, row: usize, col: usize) {
|
||||
// TODO: based on player turn, available jumps and moves.
|
||||
}
|
||||
|
||||
pub fn must_piece_jump(&self, row: usize, col: usize) {
|
||||
// TODO: based on player turn, available jumps and moves.
|
||||
}
|
||||
|
||||
pub fn change_turns(&mut self) {
|
||||
// TODO: go to the next turn...
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Board;
|
||||
use crate::BoardSize;
|
||||
|
||||
#[test]
|
||||
fn initial_international_board_setup() {
|
||||
let expected = " \
|
||||
ABCDEFGHIJ\n\
|
||||
1 ○ ○ ○ ○ ○\n\
|
||||
2○ ○ ○ ○ ○ \n\
|
||||
3 ○ ○ ○ ○ ○\n\
|
||||
4○ ○ ○ ○ ○ \n\
|
||||
5 ◰ ◰ ◰ ◰ ◰\n\
|
||||
6◰ ◰ ◰ ◰ ◰ \n\
|
||||
7 ● ● ● ● ●\n\
|
||||
8● ● ● ● ● \n\
|
||||
9 ● ● ● ● ●\n\
|
||||
10● ● ● ● ● \n\
|
||||
";
|
||||
assert_eq!(Board::new(BoardSize::International).to_string(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initial_american_board_setup() {
|
||||
let expected = " \
|
||||
ABCDEFGH\n\
|
||||
1 ○ ○ ○ ○\n\
|
||||
2○ ○ ○ ○ \n\
|
||||
3 ○ ○ ○ ○\n\
|
||||
4◰ ◰ ◰ ◰ \n\
|
||||
5 ◰ ◰ ◰ ◰\n\
|
||||
6● ● ● ● \n\
|
||||
7 ● ● ● ●\n\
|
||||
8● ● ● ● \n\
|
||||
";
|
||||
assert_eq!(Board::new(BoardSize::American).to_string(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initial_canadian_board_setup() {
|
||||
let expected = " \
|
||||
ABCDEFGHIJKL\n\
|
||||
1 ○ ○ ○ ○ ○ ○\n\
|
||||
2○ ○ ○ ○ ○ ○ \n\
|
||||
3 ○ ○ ○ ○ ○ ○\n\
|
||||
4○ ○ ○ ○ ○ ○ \n\
|
||||
5 ○ ○ ○ ○ ○ ○\n\
|
||||
6◰ ◰ ◰ ◰ ◰ ◰ \n\
|
||||
7 ◰ ◰ ◰ ◰ ◰ ◰\n\
|
||||
8● ● ● ● ● ● \n\
|
||||
9 ● ● ● ● ● ●\n\
|
||||
10● ● ● ● ● ● \n\
|
||||
11 ● ● ● ● ● ●\n\
|
||||
12● ● ● ● ● ● \n\
|
||||
";
|
||||
assert_eq!(Board::new(BoardSize::Canadian).to_string(), expected);
|
||||
}
|
||||
}
|
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 |
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,73 @@
|
|||
QT += quick multimedia multimediawidgets svg quickcontrols2
|
||||
CONFIG += c++11
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which as been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH =
|
||||
|
||||
QT_QUICK_CONTROLS_STYLE=universal
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
DISTFILES += \
|
||||
images/backdrop.jpg \
|
||||
images/splash.jpg \
|
||||
images/attack_king.png \
|
||||
images/attack_pawn.png \
|
||||
images/defend_king.png \
|
||||
images/defend_pawn.png \
|
||||
images/icon.png \
|
||||
images/idea.png \
|
||||
images/logo.png \
|
||||
images/non_play.png \
|
||||
images/play.png \
|
||||
assets/credits.md \
|
||||
assets/license.md \
|
||||
doc/AUTHORS.txt \
|
||||
doc/BUGS.txt \
|
||||
doc/Changelog.txt \
|
||||
justcheckers/justcheckers.ini \
|
||||
justcheckers/justcheckers.kv \
|
||||
COPYING.txt \
|
||||
Pipfile \
|
||||
Pipfile.lock \
|
||||
justcheckers/game/__init__.py \
|
||||
justcheckers/game/board.py \
|
||||
justcheckers/game/game.py \
|
||||
justcheckers/game/game_engine.py \
|
||||
justcheckers/game/player.py \
|
||||
justcheckers/game/rules.py \
|
||||
justcheckers/__init__.py \
|
||||
justcheckers/app.py \
|
||||
main.py \
|
||||
setup.py \
|
||||
tasks.py \
|
||||
main.qml \
|
||||
README.rst \
|
||||
buildozer.spec \
|
||||
MenuButton.qml \
|
||||
Menu.qml \
|
||||
Board.qml
|
||||
|
||||
SUBDIRS += \
|
||||
justcheckers.pro
|
|
@ -0,0 +1 @@
|
|||
__version__ = '0.3.0'
|
|
@ -0,0 +1,97 @@
|
|||
"""
|
||||
Main application for justCheckers
|
||||
|
||||
:copyright: Copyright 2004-2017, Dorian Pula <dorian.pula@amber-penguin-software.ca>
|
||||
:license: GPL v3+
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from kivy import properties
|
||||
from kivy.app import App
|
||||
from kivy.logger import Logger
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.relativelayout import RelativeLayout
|
||||
|
||||
import justcheckers
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class JustCheckersApp(App):
|
||||
title = 'justCheckers'
|
||||
icon = 'justcheckers/images/icon.png'
|
||||
use_kivy_settings = False
|
||||
|
||||
def on_start(self):
|
||||
log_system_and_game_info()
|
||||
super(JustCheckersApp, self).on_start()
|
||||
|
||||
def build_config(self, config):
|
||||
config.setdefaults('Theme', {'theme': 'Sunset', 'background': 'Sunset'})
|
||||
|
||||
def build_settings(self, settings):
|
||||
# TODO: Add turn options for music and volume.
|
||||
game_settings = [{
|
||||
"type": "options",
|
||||
"title": "Board Theme",
|
||||
"section": "Theme",
|
||||
"key": "theme",
|
||||
"options": ["Sunset", "Basic"]
|
||||
}, {
|
||||
"type": "options",
|
||||
"title": "Background",
|
||||
"section": "Theme",
|
||||
"key": "background",
|
||||
"options": ["Sunset", "Basic"]
|
||||
}]
|
||||
settings.add_json_panel("justCheckers Settings", self.config, data=json.dumps(game_settings))
|
||||
|
||||
|
||||
class GameBoard(GridLayout):
|
||||
rows = properties.NumericProperty(8)
|
||||
cols = properties.NumericProperty(8)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(GameBoard, self).__init__(**kwargs)
|
||||
for row in range(self.rows):
|
||||
for col in range(self.cols):
|
||||
source = 'play'
|
||||
if row % 2 == 0 and col % 2 == 0:
|
||||
source = 'non_play'
|
||||
elif row % 2 == 1 and col % 2 == 1:
|
||||
source = 'non_play'
|
||||
self.add_widget(GameTile(tile_state=source, coords=[row, col]))
|
||||
|
||||
|
||||
class GameTile(RelativeLayout):
|
||||
tile_state = properties.StringProperty()
|
||||
tile_coords = properties.ListProperty()
|
||||
tile_image = properties.ObjectProperty()
|
||||
tile_label = properties.ObjectProperty()
|
||||
|
||||
def __init__(self, tile_state='non_play', coords=None, **kwargs):
|
||||
super(GameTile, self).__init__(**kwargs)
|
||||
self.tile_state = tile_state
|
||||
self.coords = coords if coords else [-1, -1]
|
||||
self.tile_label.text = '{}, {}'.format(self.coords[0], self.coords[1])
|
||||
self.tile_image.source = 'images/{}.png'.format(self.tile_state)
|
||||
|
||||
|
||||
def log_system_and_game_info():
|
||||
"""Logs information about the game and system running the game."""
|
||||
Logger.info('justCheckers -- v{}'.format(justcheckers.__version__))
|
||||
|
||||
message = 'I am running on {os}.\nMy screen is {height}x{width}'
|
||||
root_window = App.get_running_app().root_window
|
||||
|
||||
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)
|
||||
|
||||
Logger.info(message.format(os=os_sys, height=root_window.height, width=root_window.width))
|
|
@ -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
|
|
@ -0,0 +1,177 @@
|
|||
#: import justcheckers justcheckers
|
||||
|
||||
ScreenManager:
|
||||
MenuScreen:
|
||||
GameScreen:
|
||||
InfoScreen:
|
||||
|
||||
<MenuScreen@Screen>:
|
||||
name: 'menu'
|
||||
Image:
|
||||
source: 'images/backdrop.jpg'
|
||||
allow_stretch: True
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
Image:
|
||||
source: 'images/logo.png'
|
||||
size_hint_y: 0.25
|
||||
allow_stretch: True
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 1, 1, 1, 0.5
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
MainMenuButtonGroup:
|
||||
size_hint_x: 0.9
|
||||
pos_hint: {'center_x': 0.5}
|
||||
Label:
|
||||
text: "Version {}".format(justcheckers.__version__)
|
||||
size_hint_y: 0.1
|
||||
pos_hint: {'center_x': 0.9}
|
||||
|
||||
|
||||
<MainMenuButtonGroup@BoxLayout>:
|
||||
orientation: "vertical"
|
||||
Button:
|
||||
text: "New Game"
|
||||
size_hint_y: 0.1
|
||||
on_press:
|
||||
root.parent.parent.manager.transition.direction = 'left'
|
||||
root.parent.parent.manager.current = 'game'
|
||||
Button:
|
||||
text: "Open Game"
|
||||
disabled: True
|
||||
size_hint_y: 0.1
|
||||
Button:
|
||||
text: "Save Game"
|
||||
disabled: True
|
||||
size_hint_y: 0.1
|
||||
Button:
|
||||
text: "About Game"
|
||||
size_hint_y: 0.1
|
||||
on_press:
|
||||
root.parent.parent.manager.transition.direction = 'left'
|
||||
root.parent.parent.manager.current = 'info'
|
||||
Button:
|
||||
text: "Settings"
|
||||
size_hint_y: 0.1
|
||||
on_press:
|
||||
app.open_settings()
|
||||
Button:
|
||||
text: "Exit"
|
||||
size_hint_y: 0.1
|
||||
on_press:
|
||||
app.stop()
|
||||
|
||||
<GameScreen@Screen>:
|
||||
name: 'game'
|
||||
Image:
|
||||
source: 'images/backdrop.jpg'
|
||||
allow_stretch: True
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
BoxLayout:
|
||||
orientation: "horizontal"
|
||||
size_hint_x: 0.9
|
||||
pos_hint: {'center_x': 0.5}
|
||||
GameBoard:
|
||||
id: game_board
|
||||
size_hint_x: 0.75
|
||||
BoxLayout:
|
||||
id: player_stats
|
||||
size_hint_x: 0.25
|
||||
orientation: "vertical"
|
||||
Button:
|
||||
text: "Player 1"
|
||||
Button:
|
||||
text: "Player 2"
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
BoxLayout:
|
||||
orientation: "horizontal"
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.1
|
||||
pos_hint: {'center_x': 0.5}
|
||||
Button:
|
||||
text: "Back to Menu"
|
||||
on_press:
|
||||
root.manager.transition.direction = 'right'
|
||||
root.manager.current = 'menu'
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
|
||||
<InfoScreen@Screen>:
|
||||
name: 'info'
|
||||
documentation: "credits"
|
||||
Image:
|
||||
source: 'images/backdrop.jpg'
|
||||
allow_stretch: True
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
RstDocument:
|
||||
source: "assets/{}.md".format(root.documentation)
|
||||
size_hint_y: 0.75
|
||||
size_hint_x: 0.9
|
||||
pos_hint: {'center_x': 0.5}
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
BoxLayout:
|
||||
orientation: "horizontal"
|
||||
size_hint_x: 0.9
|
||||
size_hint_y: 0.1
|
||||
pos_hint: {'center_x': 0.5}
|
||||
Button:
|
||||
text: "Back to Menu"
|
||||
on_press:
|
||||
root.manager.transition.direction = 'right'
|
||||
root.manager.current = 'menu'
|
||||
ToggleButton:
|
||||
id: toggle_credits
|
||||
text: "Credits"
|
||||
state: "down" if root.documentation == 'credits' else "normal"
|
||||
group: "info"
|
||||
on_state:
|
||||
if self.state == 'down': root.documentation = 'credits'
|
||||
ToggleButton
|
||||
id: toggle_license
|
||||
text: "License"
|
||||
group: "info"
|
||||
state: "down" if root.documentation == 'license' else "normal"
|
||||
on_state:
|
||||
if self.state == 'down': root.documentation = 'license'
|
||||
Label:
|
||||
size_hint_y: 0.1
|
||||
|
||||
|
||||
<GameBoard@GridLayout>:
|
||||
rows: 8
|
||||
cols: 8
|
||||
# TODO: Make sure the grid height and width is a fraction of the screen.
|
||||
row_force_default: True
|
||||
row_default_height: 50
|
||||
col_force_default: True
|
||||
col_default_width: 50
|
||||
|
||||
|
||||
<GameTile@RelativeLayout>:
|
||||
tile_state: "play"
|
||||
tile_coords: 0, 0
|
||||
tile_image: image
|
||||
tile_label: label
|
||||
Image:
|
||||
id: image
|
||||
allow_stretch: True
|
||||
Label:
|
||||
id: label
|
||||
color: [1, 0, 0, 0.75]
|
||||
font_size: "20sp"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
if (engine.rootObjects().isEmpty())
|
||||
return -1;
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
from justcheckers import app
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.JustCheckersApp().run()
|
|
@ -0,0 +1,22 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.1
|
||||
|
||||
|
||||
ApplicationWindow {
|
||||
|
||||
id: mainWindow
|
||||
property var appVersion: "0.4.0"
|
||||
|
||||
visible: true
|
||||
width: 540
|
||||
height: 960
|
||||
title: qsTr("justCheckers v" + appVersion)
|
||||
|
||||
Loader {
|
||||
id: appPage
|
||||
source: "Menu.qml"
|
||||
anchors.fill: parent
|
||||
|
||||
property var version: appVersion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>Board.qml</file>
|
||||
<file>Menu.qml</file>
|
||||
<file>images/attack_king.png</file>
|
||||
<file>images/attack_pawn.png</file>
|
||||
<file>images/backdrop.jpg</file>
|
||||
<file>images/defend_king.png</file>
|
||||
<file>images/defend_pawn.png</file>
|
||||
<file>images/icon.png</file>
|
||||
<file>images/idea.png</file>
|
||||
<file>images/logo.png</file>
|
||||
<file>images/non_play.png</file>
|
||||
<file>images/play.png</file>
|
||||
<file>images/splash.jpg</file>
|
||||
<file>MenuButton.qml</file>
|
||||
<file>assets/ping.wav</file>
|
||||
<file>qtquickcontrols2.conf</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,9 @@
|
|||
[Controls]
|
||||
Style=Material
|
||||
|
||||
[Material]
|
||||
Theme=Dark
|
||||
|
||||
[Material\Font]
|
||||
Family=Open Sans
|
||||
PixelSize=32
|
|
@ -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,61 @@
|
|||
import os
|
||||
from os import path
|
||||
import shutil
|
||||
|
||||
from invoke import task, run
|
||||
|
||||
|
||||
@task
|
||||
def run_game(ctx):
|
||||
run('python main.py')
|
||||
|
||||
|
||||
@task
|
||||
def clean(ctx):
|
||||
"""Clean generated files."""
|
||||
run('rm *.pyc')
|
||||
|
||||
|
||||
@task
|
||||
def docs(ctx):
|
||||
"""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(ctx):
|
||||
"""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(ctx):
|
||||
"""Test the coding style using Flake8."""
|
||||
run('flake8')
|
||||
|
||||
|
||||
@task
|
||||
def build_package(ctx):
|
||||
"""Prepares the project for packaging."""
|
||||
run('python setup.py sdist')
|
||||
|
||||
|
||||
@task
|
||||
def clean_package(ctx):
|
||||
"""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)
|
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
|
||||
}
|