diff --git a/tictactoe/README.md b/tictactoe/README.md index 3aa3dff7..91d37b1f 100644 --- a/tictactoe/README.md +++ b/tictactoe/README.md @@ -14,7 +14,10 @@ 1. After building the project (i.e., running `ant`), run the following command in the tictactoe folder: `java -cp bin RowGameApp` - +2.To undo a move, press the "Undo" button on the game board. This will undo the last move made by the player. The game board will be updated + to show the previous state of the game. ### How to clean up (from Terminal): 1. Run `ant clean` to clean the project (i.e., delete all generated files). + +Note: The undo feature is only available for the player's moves and not for the computer's moves. \ No newline at end of file diff --git a/tictactoe/bin/RowGameApp.class b/tictactoe/bin/RowGameApp.class new file mode 100644 index 00000000..8bd0e59c Binary files /dev/null and b/tictactoe/bin/RowGameApp.class differ diff --git a/tictactoe/bin/TestExample.class b/tictactoe/bin/TestExample.class new file mode 100644 index 00000000..4e19a93d Binary files /dev/null and b/tictactoe/bin/TestExample.class differ diff --git a/tictactoe/bin/controller/RowGameController.class b/tictactoe/bin/controller/RowGameController.class new file mode 100644 index 00000000..65a867e7 Binary files /dev/null and b/tictactoe/bin/controller/RowGameController.class differ diff --git a/tictactoe/bin/model/Player.class b/tictactoe/bin/model/Player.class new file mode 100644 index 00000000..ea3433f4 Binary files /dev/null and b/tictactoe/bin/model/Player.class differ diff --git a/tictactoe/bin/model/RowBlockModel.class b/tictactoe/bin/model/RowBlockModel.class new file mode 100644 index 00000000..4cf61cfc Binary files /dev/null and b/tictactoe/bin/model/RowBlockModel.class differ diff --git a/tictactoe/bin/model/RowGameModel$Move.class b/tictactoe/bin/model/RowGameModel$Move.class new file mode 100644 index 00000000..16d335a1 Binary files /dev/null and b/tictactoe/bin/model/RowGameModel$Move.class differ diff --git a/tictactoe/bin/model/RowGameModel.class b/tictactoe/bin/model/RowGameModel.class new file mode 100644 index 00000000..999566d3 Binary files /dev/null and b/tictactoe/bin/model/RowGameModel.class differ diff --git a/tictactoe/bin/view/BlockIndex.class b/tictactoe/bin/view/BlockIndex.class new file mode 100644 index 00000000..b367ee9a Binary files /dev/null and b/tictactoe/bin/view/BlockIndex.class differ diff --git a/tictactoe/bin/view/GameBoardView$1.class b/tictactoe/bin/view/GameBoardView$1.class new file mode 100644 index 00000000..8efc7056 Binary files /dev/null and b/tictactoe/bin/view/GameBoardView$1.class differ diff --git a/tictactoe/bin/view/GameBoardView.class b/tictactoe/bin/view/GameBoardView.class new file mode 100644 index 00000000..533fdfb4 Binary files /dev/null and b/tictactoe/bin/view/GameBoardView.class differ diff --git a/tictactoe/bin/view/GameStatusView.class b/tictactoe/bin/view/GameStatusView.class new file mode 100644 index 00000000..1dc666b1 Binary files /dev/null and b/tictactoe/bin/view/GameStatusView.class differ diff --git a/tictactoe/bin/view/RowGameGUI$1.class b/tictactoe/bin/view/RowGameGUI$1.class new file mode 100644 index 00000000..c802187e Binary files /dev/null and b/tictactoe/bin/view/RowGameGUI$1.class differ diff --git a/tictactoe/bin/view/RowGameGUI$2.class b/tictactoe/bin/view/RowGameGUI$2.class new file mode 100644 index 00000000..7b20fefd Binary files /dev/null and b/tictactoe/bin/view/RowGameGUI$2.class differ diff --git a/tictactoe/bin/view/RowGameGUI.class b/tictactoe/bin/view/RowGameGUI.class new file mode 100644 index 00000000..fdecc801 Binary files /dev/null and b/tictactoe/bin/view/RowGameGUI.class differ diff --git a/tictactoe/bin/view/View.class b/tictactoe/bin/view/View.class new file mode 100644 index 00000000..43722c2e Binary files /dev/null and b/tictactoe/bin/view/View.class differ diff --git a/tictactoe/jdoc/RowGameApp.html b/tictactoe/jdoc/RowGameApp.html new file mode 100644 index 00000000..bd69cbb2 --- /dev/null +++ b/tictactoe/jdoc/RowGameApp.html @@ -0,0 +1,161 @@ + + + + +RowGameApp (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+

类 RowGameApp

+
+
java.lang.Object +
RowGameApp
+
+
+
+
public class RowGameApp +extends Object
+
+
+ +
+
+
    + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      RowGameApp

      +
      public RowGameApp()
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      main

      +
      public static void main(String[] args)
      +
      Starts a new game in the GUI.
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/allclasses-index.html b/tictactoe/jdoc/allclasses-index.html new file mode 100644 index 00000000..ff912da5 --- /dev/null +++ b/tictactoe/jdoc/allclasses-index.html @@ -0,0 +1,106 @@ + + + + +All Classes and Interfaces (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

All Classes and Interfaces

+
+
+
+
+
+
+
说明
+ +
 
+ +
+
The GameBoardView class visualizes the game board of blocks.
+
+ +
+
The GameStatusView class visualizes the game status as either in progress, + current player's turn, or finished, either win or tie.
+
+ +
 
+ +
+
The TicTacToeBlock class represents a given block in the game.
+
+ +
 
+ +
 
+ +
+
The RowGameGUI class is applying the Composite design pattern.
+
+ +
 
+ +
+
Inner class to represent a move made by a player.
+
+ +
+
The View interfaces supports updating the visualizations of the Model.
+
+
+
+
+
+
+
+ + diff --git a/tictactoe/jdoc/allpackages-index.html b/tictactoe/jdoc/allpackages-index.html new file mode 100644 index 00000000..4b6a04f9 --- /dev/null +++ b/tictactoe/jdoc/allpackages-index.html @@ -0,0 +1,71 @@ + + + + +所有程序包 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

所有程序包

+
+
程序包概要
+
+
程序包
+
说明
+ +
 
+ +
 
+ +
 
+ +
 
+
+
+
+
+ + diff --git a/tictactoe/jdoc/class-use/RowGameApp.html b/tictactoe/jdoc/class-use/RowGameApp.html new file mode 100644 index 00000000..9c3d7322 --- /dev/null +++ b/tictactoe/jdoc/class-use/RowGameApp.html @@ -0,0 +1,58 @@ + + + + +类 RowGameApp的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

类的使用
RowGameApp

+
+没有RowGameApp的用法
+
+
+ + diff --git a/tictactoe/jdoc/constant-values.html b/tictactoe/jdoc/constant-values.html new file mode 100644 index 00000000..33acfec4 --- /dev/null +++ b/tictactoe/jdoc/constant-values.html @@ -0,0 +1,80 @@ + + + + +常量字段值 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

常量字段值

+
+

目录

+ +
+
+
+

model.*

+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/controller/RowGameController.html b/tictactoe/jdoc/controller/RowGameController.html new file mode 100644 index 00000000..8e0536b3 --- /dev/null +++ b/tictactoe/jdoc/controller/RowGameController.html @@ -0,0 +1,249 @@ + + + + +RowGameController (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+
程序包 controller
+

类 RowGameController

+
+
java.lang.Object +
controller.RowGameController
+
+
+
+
public class RowGameController +extends Object
+
+
+ +
+
+
    + +
  • +
    +

    字段详细资料

    + +
    +
  • + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      RowGameController

      +
      public RowGameController()
      +
      Creates a new game initializing the GUI.
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      undoMove

      +
      public void undoMove()
      +
      +
    • +
    • +
      +

      move

      +
      public void move(JButton block)
      +
      Moves the current player into the given block.
      +
      +
      参数:
      +
      block - The block to be moved to by the current player
      +
      +
      +
    • +
    • +
      +

      endGame

      +
      public void endGame()
      +
      Ends the game disallowing further player turns.
      +
      +
    • +
    • +
      +

      resetGame

      +
      public void resetGame()
      +
      Resets the game to be able to start playing again.
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/controller/class-use/RowGameController.html b/tictactoe/jdoc/controller/class-use/RowGameController.html new file mode 100644 index 00000000..55846de4 --- /dev/null +++ b/tictactoe/jdoc/controller/class-use/RowGameController.html @@ -0,0 +1,89 @@ + + + + +类 controller.RowGameController的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

类的使用
controller.RowGameController

+
+
使用RowGameController的程序包
+
+
程序包
+
说明
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/controller/package-summary.html b/tictactoe/jdoc/controller/package-summary.html new file mode 100644 index 00000000..7fb4843b --- /dev/null +++ b/tictactoe/jdoc/controller/package-summary.html @@ -0,0 +1,83 @@ + + + + +controller (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包 controller

+
+
+
package controller
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/controller/package-tree.html b/tictactoe/jdoc/controller/package-tree.html new file mode 100644 index 00000000..f95c0d85 --- /dev/null +++ b/tictactoe/jdoc/controller/package-tree.html @@ -0,0 +1,72 @@ + + + + +controller 类分层结构 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包controller的分层结构

+程序包分层结构: + +
+
+

类分层结构

+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/controller/package-use.html b/tictactoe/jdoc/controller/package-use.html new file mode 100644 index 00000000..1e2cffcd --- /dev/null +++ b/tictactoe/jdoc/controller/package-use.html @@ -0,0 +1,80 @@ + + + + +程序包 controller的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包的使用
controller

+
+
使用controller的程序包
+
+
程序包
+
说明
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/element-list b/tictactoe/jdoc/element-list new file mode 100644 index 00000000..0740a3af --- /dev/null +++ b/tictactoe/jdoc/element-list @@ -0,0 +1,4 @@ +未命名程序包 +controller +model +view diff --git a/tictactoe/jdoc/help-doc.html b/tictactoe/jdoc/help-doc.html new file mode 100644 index 00000000..0e8ff167 --- /dev/null +++ b/tictactoe/jdoc/help-doc.html @@ -0,0 +1,187 @@ + + + + +API 帮助 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+

此 API 文档的组织方式

+ +
+
+

Navigation

+Starting from the 概览 page, you can browse the documentation using the links in each page, and in the navigation bar at the top of each page. The 索引 and Search box allow you to navigate to specific declarations and summary pages, including: 所有程序包, All Classes and Interfaces + +
+
+
+

Kinds of Pages

+The following sections describe the different kinds of pages in this collection. +
+

概览

+

概览 页面是此 API 文档的首页, 提供了所有程序包的列表及其概要。此页面也可能包含这些程序包的总体说明。

+
+
+

程序包

+

每个程序包都有一页,其中包含它的类和接口的列表及其概要。这些页可以包含六个类别:

+
    +
  • 接口
  • +
  • +
  • Enum Classes
  • +
  • 异常错误
  • +
  • 错误
  • +
  • Annotation Interfaces
  • +
+
+
+

类或接口

+

每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:

+
    +
  • 类继承图
  • +
  • 直接子类
  • +
  • 所有已知子接口
  • +
  • 所有已知实现类
  • +
  • 类或接口声明
  • +
  • 类或接口说明
  • +
+
+
    +
  • 嵌套类概要
  • +
  • 枚举常量概要
  • +
  • 字段概要
  • +
  • 属性概要
  • +
  • 构造器概要
  • +
  • 方法概要
  • +
  • 必需元素概要
  • +
  • 可选元素概要
  • +
+
+
    +
  • 枚举常量详细资料
  • +
  • 字段详细资料
  • +
  • 属性详细资料
  • +
  • 构造器详细资料
  • +
  • 方法详细资料
  • +
  • 元素详细资料
  • +
+

Note: Annotation interfaces have required and optional elements, but not methods. Only enum classes have enum constants. The components of a record class are displayed as part of the declaration of the record class. Properties are a feature of JavaFX.

+

The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

+
+
+

Other Files

+

Packages and modules may contain pages with additional information related to the declarations nearby.

+
+
+

使用

+

每个已文档化的程序包、类和接口都有各自的“使用”页。此页介绍了使用给定类或程序包的任何部分的程序包、类、方法、构造器和字段。对于给定的类或接口 A,其“使用”页包含 A 的子类、声明为 A 的字段、返回 A 的方法以及带有类型为 A 的参数的方法和构造器。访问此页的方法是:首先转至程序包、类或接口,然后单击导航栏中的“使用”链接。

+
+
+

树 (类分层结构)

+

对于所有程序包,都有一个 类分层结构 页,以及每个程序包的分层结构。每个分层结构页都包含类的列表和接口的列表。从 java.lang.Object 开始,按继承结构对类进行排列。接口不从 java.lang.Object 继承。

+
    +
  • 查看“概览”页面时, 单击 "树" 将显示所有程序包的分层结构。
  • +
  • 查看特定程序包、类或接口页时,单击“树”将仅显示该程序包的分层结构。
  • +
+
+
+

常量字段值

+

常量字段值页面列出了静态最终字段及其值。

+
+
+

All Packages

+

The 所有程序包 page contains an alphabetic index of all packages contained in the documentation.

+
+
+

All Classes and Interfaces

+

The All Classes and Interfaces page contains an alphabetic index of all classes and interfaces contained in the documentation, including annotation interfaces, enum classes, and record classes.

+
+
+

索引

+

索引 包含所有类、接口、构造器、方法和字段的按字母顺序排列的索引,以及所有程序包和所有类的列表。

+
+
+
+此帮助文件适用于由标准 doclet 生成的 API 文档。
+
+
+ + diff --git a/tictactoe/jdoc/index-all.html b/tictactoe/jdoc/index-all.html new file mode 100644 index 00000000..02242f0f --- /dev/null +++ b/tictactoe/jdoc/index-all.html @@ -0,0 +1,333 @@ + + + + +索引 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

索引

+
+A B C E F G I M P R S T U V 
All Classes and Interfaces|常量字段值|所有程序包 +

A

+
+
addView(View) - 类中的方法 view.RowGameGUI
+
 
+
+

B

+
+
BlockIndex - view中的类
+
 
+
BlockIndex(int, int) - 类的构造器 view.BlockIndex
+
 
+
blocks - 类中的变量 view.GameBoardView
+
 
+
blocksData - 类中的变量 model.RowGameModel
+
 
+
+

C

+
+
col - 类中的变量 model.RowGameModel.Move
+
 
+
column - 类中的变量 view.BlockIndex
+
 
+
contents - 类中的变量 model.RowBlockModel
+
+
The current value of the contents of this block
+
+
controller - 程序包 controller
+
 
+
+

E

+
+
endGame() - 类中的方法 controller.RowGameController
+
+
Ends the game disallowing further player turns.
+
+
+

F

+
+
finalResult - 类中的变量 model.RowGameModel
+
 
+
+

G

+
+
game - 类中的变量 model.RowBlockModel
+
+
The game that contains this block
+
+
GAME_END_NOWINNER - 类中的静态变量 model.RowGameModel
+
 
+
gameBoardView - 类中的变量 view.RowGameGUI
+
 
+
GameBoardView - view中的类
+
+
The GameBoardView class visualizes the game board of blocks.
+
+
GameBoardView(JPanel, RowGameController) - 类的构造器 view.GameBoardView
+
 
+
gameModel - 类中的变量 controller.RowGameController
+
 
+
gameModel - 类中的变量 view.RowGameGUI
+
 
+
GameStatusView - view中的类
+
+
The GameStatusView class visualizes the game status as either in progress, + current player's turn, or finished, either win or tie.
+
+
GameStatusView(JPanel) - 类的构造器 view.GameStatusView
+
 
+
gameView - 类中的变量 controller.RowGameController
+
 
+
getBlockIndex(JButton) - 类中的方法 view.GameBoardView
+
+
Returns the BlockIndex (pair of row and column) of the given block + if it is part of this game board and returns null otherwise.
+
+
getBlockIndex(JButton) - 类中的方法 view.RowGameGUI
+
 
+
getCol() - 类中的方法 model.RowGameModel.Move
+
 
+
getColumn() - 类中的方法 view.BlockIndex
+
 
+
getContents() - 类中的方法 model.RowBlockModel
+
+
Returns the non-null String value of the contents of this block.
+
+
getFinalResult() - 类中的方法 model.RowGameModel
+
 
+
getGame() - 类中的方法 model.RowBlockModel
+
 
+
getID() - enum class中的方法 model.Player
+
 
+
getIsLegalMove() - 类中的方法 model.RowBlockModel
+
 
+
getPlayer() - 类中的方法 model.RowGameModel
+
 
+
getPlayer() - 类中的方法 model.RowGameModel.Move
+
 
+
getRow() - 类中的方法 model.RowGameModel.Move
+
 
+
getRow() - 类中的方法 view.BlockIndex
+
 
+
gui - 类中的变量 view.RowGameGUI
+
 
+
+

I

+
+
id - enum class中的变量 model.Player
+
 
+
isLegalMove - 类中的变量 model.RowBlockModel
+
+
Whether or not it is currently legal to move into this block
+
+
+

M

+
+
main(String[]) - 类中的静态方法 RowGameApp
+
+
Starts a new game in the GUI.
+
+
matches(int, int) - 类中的方法 view.BlockIndex
+
 
+
model - 程序包 model
+
 
+
move(JButton) - 类中的方法 controller.RowGameController
+
+
Moves the current player into the given block.
+
+
Move(int, int, Player) - 类的构造器 model.RowGameModel.Move
+
 
+
moveHistory - 类中的变量 model.RowGameModel
+
 
+
movesLeft - 类中的变量 model.RowGameModel
+
 
+
+

P

+
+
player - 类中的变量 model.RowGameModel.Move
+
 
+
player - 类中的变量 model.RowGameModel
+
+
The current player taking their turn
+
+
Player - model中的Enum Class
+
 
+
Player(int) - enum class的构造器 model.Player
+
 
+
PLAYER_1 - enum class 中的枚举常量 model.Player
+
 
+
PLAYER_2 - enum class 中的枚举常量 model.Player
+
 
+
playerturn - 类中的变量 view.GameStatusView
+
 
+
+

R

+
+
recordMove(int, int, Player) - 类中的方法 model.RowGameModel
+
+
Method to record a move in the move history stack.
+
+
reset - 类中的变量 view.RowGameGUI
+
 
+
reset() - 类中的方法 model.RowBlockModel
+
+
Resets this block before starting a new game.
+
+
resetGame() - 类中的方法 controller.RowGameController
+
+
Resets the game to be able to start playing again.
+
+
row - 类中的变量 model.RowGameModel.Move
+
 
+
row - 类中的变量 view.BlockIndex
+
 
+
RowBlockModel - model中的类
+
+
The TicTacToeBlock class represents a given block in the game.
+
+
RowBlockModel(RowGameModel) - 类的构造器 model.RowBlockModel
+
+
Creates a new block that will be contained in the given game.
+
+
RowGameApp - Unnamed Package中的类
+
 
+
RowGameApp() - 类的构造器 RowGameApp
+
 
+
RowGameController - controller中的类
+
 
+
RowGameController() - 类的构造器 controller.RowGameController
+
+
Creates a new game initializing the GUI.
+
+
RowGameGUI - view中的类
+
+
The RowGameGUI class is applying the Composite design pattern.
+
+
RowGameGUI(RowGameController) - 类的构造器 view.RowGameGUI
+
+
Creates a new game initializing the GUI.
+
+
RowGameModel - model中的类
+
 
+
RowGameModel() - 类的构造器 model.RowGameModel
+
 
+
RowGameModel.Move - model中的类
+
+
Inner class to represent a move made by a player.
+
+
+

S

+
+
setContents(String) - 类中的方法 model.RowBlockModel
+
+
Sets the contents of this block to the given value.
+
+
setFinalResult(String) - 类中的方法 model.RowGameModel
+
 
+
setIsLegalMove(boolean) - 类中的方法 model.RowBlockModel
+
 
+
setPlayer(Player) - 类中的方法 model.RowGameModel
+
 
+
+

T

+
+
toString() - enum class中的方法 model.Player
+
 
+
+

U

+
+
undo - 类中的变量 controller.RowGameController
+
 
+
undo - 类中的变量 view.RowGameGUI
+
 
+
undoMove() - 类中的方法 controller.RowGameController
+
 
+
undoMove() - 类中的方法 model.RowGameModel
+
+
Method to handle undo functionality.
+
+
update(RowGameModel) - 类中的方法 view.GameBoardView
+
 
+
update(RowGameModel) - 类中的方法 view.GameStatusView
+
 
+
update(RowGameModel) - 类中的方法 view.RowGameGUI
+
 
+
update(RowGameModel) - 接口中的方法 view.View
+
 
+
updateBlock(RowGameModel, int, int) - 类中的方法 view.GameBoardView
+
+
Updates the block at the given row and column + after one of the player's moves.
+
+
+

V

+
+
valueOf(String) - enum class中的静态方法 model.Player
+
+
Returns the enum constant of this class with the specified name.
+
+
values() - enum class中的静态方法 model.Player
+
+
Returns an array containing the constants of this enum class, in +the order they are declared.
+
+
view - 程序包 view
+
 
+
View - view中的接口
+
+
The View interfaces supports updating the visualizations of the Model.
+
+
viewList - 类中的变量 view.RowGameGUI
+
+
For the Composite design pattern, the RowGameGUI is the Composite
+
+
+A B C E F G I M P R S T U V 
All Classes and Interfaces|常量字段值|所有程序包
+
+
+ + diff --git a/tictactoe/jdoc/index.html b/tictactoe/jdoc/index.html new file mode 100644 index 00000000..a15b166b --- /dev/null +++ b/tictactoe/jdoc/index.html @@ -0,0 +1,68 @@ + + + + +概览 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+
程序包
+
+
程序包
+
说明
+ +
 
+ +
 
+ +
 
+
+
+
+
+
+ + diff --git a/tictactoe/jdoc/jquery-ui.overrides.css b/tictactoe/jdoc/jquery-ui.overrides.css new file mode 100644 index 00000000..03c010ba --- /dev/null +++ b/tictactoe/jdoc/jquery-ui.overrides.css @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + /* Overrides the color of selection used in jQuery UI */ + background: #F8981D; + border: 1px solid #F8981D; +} diff --git a/tictactoe/jdoc/legal/COPYRIGHT b/tictactoe/jdoc/legal/COPYRIGHT new file mode 100644 index 00000000..ca74fffd --- /dev/null +++ b/tictactoe/jdoc/legal/COPYRIGHT @@ -0,0 +1 @@ +Please see ..\java.base\COPYRIGHT diff --git a/tictactoe/jdoc/legal/LICENSE b/tictactoe/jdoc/legal/LICENSE new file mode 100644 index 00000000..4ad9fe40 --- /dev/null +++ b/tictactoe/jdoc/legal/LICENSE @@ -0,0 +1 @@ +Please see ..\java.base\LICENSE diff --git a/tictactoe/jdoc/legal/jquery.md b/tictactoe/jdoc/legal/jquery.md new file mode 100644 index 00000000..f7b72e3f --- /dev/null +++ b/tictactoe/jdoc/legal/jquery.md @@ -0,0 +1,72 @@ +## jQuery v3.6.0 + +### jQuery License +``` +jQuery v 3.6.0 +Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +****************************************** + +The jQuery JavaScript Library v3.6.0 also includes Sizzle.js + +Sizzle.js includes the following license: + +Copyright JS Foundation and other contributors, https://js.foundation/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/sizzle + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +********************* + +``` diff --git a/tictactoe/jdoc/legal/jqueryUI.md b/tictactoe/jdoc/legal/jqueryUI.md new file mode 100644 index 00000000..8031bdb5 --- /dev/null +++ b/tictactoe/jdoc/legal/jqueryUI.md @@ -0,0 +1,49 @@ +## jQuery UI v1.12.1 + +### jQuery UI License +``` +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +``` diff --git a/tictactoe/jdoc/member-search-index.js b/tictactoe/jdoc/member-search-index.js new file mode 100644 index 00000000..2540a71f --- /dev/null +++ b/tictactoe/jdoc/member-search-index.js @@ -0,0 +1 @@ +memberSearchIndex = [{"p":"view","c":"RowGameGUI","l":"addView(View)","u":"addView(view.View)"},{"p":"view","c":"BlockIndex","l":"BlockIndex(int, int)","u":"%3Cinit%3E(int,int)"},{"p":"view","c":"GameBoardView","l":"blocks"},{"p":"model","c":"RowGameModel","l":"blocksData"},{"p":"model","c":"RowGameModel.Move","l":"col"},{"p":"view","c":"BlockIndex","l":"column"},{"p":"model","c":"RowBlockModel","l":"contents"},{"p":"controller","c":"RowGameController","l":"endGame()"},{"p":"model","c":"RowGameModel","l":"finalResult"},{"p":"model","c":"RowBlockModel","l":"game"},{"p":"model","c":"RowGameModel","l":"GAME_END_NOWINNER"},{"p":"view","c":"RowGameGUI","l":"gameBoardView"},{"p":"view","c":"GameBoardView","l":"GameBoardView(JPanel, RowGameController)","u":"%3Cinit%3E(javax.swing.JPanel,controller.RowGameController)"},{"p":"controller","c":"RowGameController","l":"gameModel"},{"p":"view","c":"RowGameGUI","l":"gameModel"},{"p":"view","c":"GameStatusView","l":"GameStatusView(JPanel)","u":"%3Cinit%3E(javax.swing.JPanel)"},{"p":"controller","c":"RowGameController","l":"gameView"},{"p":"view","c":"GameBoardView","l":"getBlockIndex(JButton)","u":"getBlockIndex(javax.swing.JButton)"},{"p":"view","c":"RowGameGUI","l":"getBlockIndex(JButton)","u":"getBlockIndex(javax.swing.JButton)"},{"p":"model","c":"RowGameModel.Move","l":"getCol()"},{"p":"view","c":"BlockIndex","l":"getColumn()"},{"p":"model","c":"RowBlockModel","l":"getContents()"},{"p":"model","c":"RowGameModel","l":"getFinalResult()"},{"p":"model","c":"RowBlockModel","l":"getGame()"},{"p":"model","c":"Player","l":"getID()"},{"p":"model","c":"RowBlockModel","l":"getIsLegalMove()"},{"p":"model","c":"RowGameModel","l":"getPlayer()"},{"p":"model","c":"RowGameModel.Move","l":"getPlayer()"},{"p":"model","c":"RowGameModel.Move","l":"getRow()"},{"p":"view","c":"BlockIndex","l":"getRow()"},{"p":"view","c":"RowGameGUI","l":"gui"},{"p":"model","c":"Player","l":"id"},{"p":"model","c":"RowBlockModel","l":"isLegalMove"},{"p":"","c":"RowGameApp","l":"main(String[])","u":"main(java.lang.String[])"},{"p":"view","c":"BlockIndex","l":"matches(int, int)","u":"matches(int,int)"},{"p":"model","c":"RowGameModel.Move","l":"Move(int, int, Player)","u":"%3Cinit%3E(int,int,model.Player)"},{"p":"controller","c":"RowGameController","l":"move(JButton)","u":"move(javax.swing.JButton)"},{"p":"model","c":"RowGameModel","l":"moveHistory"},{"p":"model","c":"RowGameModel","l":"movesLeft"},{"p":"model","c":"RowGameModel.Move","l":"player"},{"p":"model","c":"RowGameModel","l":"player"},{"p":"model","c":"Player","l":"PLAYER_1"},{"p":"model","c":"Player","l":"PLAYER_2"},{"p":"model","c":"Player","l":"Player(int)","u":"%3Cinit%3E(int)"},{"p":"view","c":"GameStatusView","l":"playerturn"},{"p":"model","c":"RowGameModel","l":"recordMove(int, int, Player)","u":"recordMove(int,int,model.Player)"},{"p":"view","c":"RowGameGUI","l":"reset"},{"p":"model","c":"RowBlockModel","l":"reset()"},{"p":"controller","c":"RowGameController","l":"resetGame()"},{"p":"model","c":"RowGameModel.Move","l":"row"},{"p":"view","c":"BlockIndex","l":"row"},{"p":"model","c":"RowBlockModel","l":"RowBlockModel(RowGameModel)","u":"%3Cinit%3E(model.RowGameModel)"},{"p":"","c":"RowGameApp","l":"RowGameApp()","u":"%3Cinit%3E()"},{"p":"controller","c":"RowGameController","l":"RowGameController()","u":"%3Cinit%3E()"},{"p":"view","c":"RowGameGUI","l":"RowGameGUI(RowGameController)","u":"%3Cinit%3E(controller.RowGameController)"},{"p":"model","c":"RowGameModel","l":"RowGameModel()","u":"%3Cinit%3E()"},{"p":"model","c":"RowBlockModel","l":"setContents(String)","u":"setContents(java.lang.String)"},{"p":"model","c":"RowGameModel","l":"setFinalResult(String)","u":"setFinalResult(java.lang.String)"},{"p":"model","c":"RowBlockModel","l":"setIsLegalMove(boolean)"},{"p":"model","c":"RowGameModel","l":"setPlayer(Player)","u":"setPlayer(model.Player)"},{"p":"model","c":"Player","l":"toString()"},{"p":"controller","c":"RowGameController","l":"undo"},{"p":"view","c":"RowGameGUI","l":"undo"},{"p":"controller","c":"RowGameController","l":"undoMove()"},{"p":"model","c":"RowGameModel","l":"undoMove()"},{"p":"view","c":"GameBoardView","l":"update(RowGameModel)","u":"update(model.RowGameModel)"},{"p":"view","c":"GameStatusView","l":"update(RowGameModel)","u":"update(model.RowGameModel)"},{"p":"view","c":"RowGameGUI","l":"update(RowGameModel)","u":"update(model.RowGameModel)"},{"p":"view","c":"View","l":"update(RowGameModel)","u":"update(model.RowGameModel)"},{"p":"view","c":"GameBoardView","l":"updateBlock(RowGameModel, int, int)","u":"updateBlock(model.RowGameModel,int,int)"},{"p":"model","c":"Player","l":"valueOf(String)","u":"valueOf(java.lang.String)"},{"p":"model","c":"Player","l":"values()"},{"p":"view","c":"RowGameGUI","l":"viewList"}];updateSearchResults(); \ No newline at end of file diff --git a/tictactoe/jdoc/model/Player.html b/tictactoe/jdoc/model/Player.html new file mode 100644 index 00000000..6a6c2b5c --- /dev/null +++ b/tictactoe/jdoc/model/Player.html @@ -0,0 +1,298 @@ + + + + +Player (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+
程序包 model
+

Enum Class Player

+
+ +
+
+
所有已实现的接口:
+
Serializable, Comparable<Player>, Constable
+
+
+
public enum Player +extends Enum<Player>
+
+
+ +
+
+
    + +
  • +
    +

    枚举常量详细资料

    +
      +
    • +
      +

      PLAYER_1

      +
      public static final Player PLAYER_1
      +
      +
    • +
    • +
      +

      PLAYER_2

      +
      public static final Player PLAYER_2
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    字段详细资料

    +
      +
    • +
      +

      id

      +
      private int id
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      Player

      +
      private Player(int id)
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      values

      +
      public static Player[] values()
      +
      Returns an array containing the constants of this enum class, in +the order they are declared.
      +
      +
      返回:
      +
      an array containing the constants of this enum class, in the order they are declared
      +
      +
      +
    • +
    • +
      +

      valueOf

      +
      public static Player valueOf(String name)
      +
      Returns the enum constant of this class with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this class. (Extraneous whitespace characters are +not permitted.)
      +
      +
      参数:
      +
      name - 要返回的枚举常量的名称。
      +
      返回:
      +
      返回带有指定名称的枚举常量
      +
      抛出:
      +
      IllegalArgumentException - if this enum class has no constant with the specified name
      +
      NullPointerException - 如果参数为空值
      +
      +
      +
    • +
    • +
      +

      getID

      +
      public int getID()
      +
      +
    • +
    • +
      +

      toString

      +
      public String toString()
      +
      +
      覆盖:
      +
      toString 在类中 Enum<Player>
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/model/RowBlockModel.html b/tictactoe/jdoc/model/RowBlockModel.html new file mode 100644 index 00000000..36053e70 --- /dev/null +++ b/tictactoe/jdoc/model/RowBlockModel.html @@ -0,0 +1,289 @@ + + + + +RowBlockModel (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+
程序包 model
+

类 RowBlockModel

+
+
java.lang.Object +
model.RowBlockModel
+
+
+
+
public class RowBlockModel +extends Object
+
The TicTacToeBlock class represents a given block in the game.
+
+
+ +
+
+
    + +
  • +
    +

    字段详细资料

    +
      +
    • +
      +

      game

      +
      private RowGameModel game
      +
      The game that contains this block
      +
      +
    • +
    • +
      +

      contents

      +
      private String contents
      +
      The current value of the contents of this block
      +
      +
    • +
    • +
      +

      isLegalMove

      +
      private boolean isLegalMove
      +
      Whether or not it is currently legal to move into this block
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      RowBlockModel

      +
      public RowBlockModel(RowGameModel game)
      +
      Creates a new block that will be contained in the given game.
      +
      +
      参数:
      +
      game - The game that will contain the new block
      +
      抛出:
      +
      IllegalArgumentException - When the given game is null
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      getGame

      +
      public RowGameModel getGame()
      +
      +
    • +
    • +
      +

      setContents

      +
      public void setContents(String value)
      +
      Sets the contents of this block to the given value.
      +
      +
      参数:
      +
      value - The new value for the contents of this block
      +
      抛出:
      +
      IllegalArgumentException - When the given value is null
      +
      +
      +
    • +
    • +
      +

      getContents

      +
      public String getContents()
      +
      Returns the non-null String value of the contents of this block.
      +
      +
      返回:
      +
      The non-null String value
      +
      +
      +
    • +
    • +
      +

      setIsLegalMove

      +
      public void setIsLegalMove(boolean isLegalMove)
      +
      +
    • +
    • +
      +

      getIsLegalMove

      +
      public boolean getIsLegalMove()
      +
      +
    • +
    • +
      +

      reset

      +
      public void reset()
      +
      Resets this block before starting a new game.
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/model/RowGameModel.Move.html b/tictactoe/jdoc/model/RowGameModel.Move.html new file mode 100644 index 00000000..cafaa0f5 --- /dev/null +++ b/tictactoe/jdoc/model/RowGameModel.Move.html @@ -0,0 +1,233 @@ + + + + +RowGameModel.Move (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+
程序包 model
+

类 RowGameModel.Move

+
+
java.lang.Object +
model.RowGameModel.Move
+
+
+
+
封闭类:
+
RowGameModel
+
+
+
private static class RowGameModel.Move +extends Object
+
Inner class to represent a move made by a player.
+
+
+ +
+
+
    + +
  • +
    +

    字段详细资料

    +
      +
    • +
      +

      row

      +
      private int row
      +
      +
    • +
    • +
      +

      col

      +
      private int col
      +
      +
    • +
    • +
      +

      player

      +
      private Player player
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      Move

      +
      public Move(int row, + int col, + Player player)
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      getRow

      +
      public int getRow()
      +
      +
    • +
    • +
      +

      getCol

      +
      public int getCol()
      +
      +
    • +
    • +
      +

      getPlayer

      +
      public Player getPlayer()
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/model/RowGameModel.html b/tictactoe/jdoc/model/RowGameModel.html new file mode 100644 index 00000000..c5dfba76 --- /dev/null +++ b/tictactoe/jdoc/model/RowGameModel.html @@ -0,0 +1,324 @@ + + + + +RowGameModel (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+ +
+
程序包 model
+

类 RowGameModel

+
+
java.lang.Object +
model.RowGameModel
+
+
+
+
public class RowGameModel +extends Object
+
+
+ +
+
+
    + +
  • +
    +

    字段详细资料

    +
      +
    • +
      +

      GAME_END_NOWINNER

      +
      public static final String GAME_END_NOWINNER
      +
      +
      另请参阅:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      blocksData

      +
      public RowBlockModel[][] blocksData
      +
      +
    • +
    • +
      +

      player

      +
      private Player player
      +
      The current player taking their turn
      +
      +
    • +
    • +
      +

      movesLeft

      +
      public int movesLeft
      +
      +
    • +
    • +
      +

      finalResult

      +
      public String finalResult
      +
      +
    • +
    • +
      +

      moveHistory

      +
      private Stack<RowGameModel.Move> moveHistory
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    构造器详细资料

    +
      +
    • +
      +

      RowGameModel

      +
      public RowGameModel()
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    方法详细资料

    +
      +
    • +
      +

      getPlayer

      +
      public Player getPlayer()
      +
      +
    • +
    • +
      +

      setPlayer

      +
      public void setPlayer(Player player)
      +
      +
    • +
    • +
      +

      getFinalResult

      +
      public String getFinalResult()
      +
      +
    • +
    • +
      +

      setFinalResult

      +
      public void setFinalResult(String finalResult)
      +
      +
    • +
    • +
      +

      undoMove

      +
      public void undoMove()
      +
      Method to handle undo functionality. Allows undoing the previous move if + there + are moves to undo.
      +
      +
    • +
    • +
      +

      recordMove

      +
      public void recordMove(int row, + int col, + Player player)
      +
      Method to record a move in the move history stack.
      +
      +
      参数:
      +
      row - The row index of the block where the move was made
      +
      col - The column index of the block where the move was made
      +
      player - The player who made the move
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/tictactoe/jdoc/model/class-use/Player.html b/tictactoe/jdoc/model/class-use/Player.html new file mode 100644 index 00000000..4acbd992 --- /dev/null +++ b/tictactoe/jdoc/model/class-use/Player.html @@ -0,0 +1,138 @@ + + + + +Enum Class model.Player的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

Enum Class的使用
model.Player

+
+
使用Player的程序包
+
+
程序包
+
说明
+ +
 
+
+
+
    +
  • +
    +

    modelPlayer的使用

    +
    声明为Playermodel中的字段
    +
    +
    修饰符和类型
    +
    字段
    +
    说明
    +
    private Player
    +
    RowGameModel.Move.player
    +
     
    +
    private Player
    +
    RowGameModel.player
    +
    +
    The current player taking their turn
    +
    +
    +
    返回Playermodel中的方法
    +
    +
    修饰符和类型
    +
    方法
    +
    说明
    + +
    RowGameModel.getPlayer()
    +
     
    + +
    RowGameModel.Move.getPlayer()
    +
     
    +
    static Player
    +
    Player.valueOf(String name)
    +
    +
    Returns the enum constant of this class with the specified name.
    +
    +
    static Player[]
    +
    Player.values()
    +
    +
    Returns an array containing the constants of this enum class, in +the order they are declared.
    +
    +
    +
    参数类型为Playermodel中的方法
    +
    +
    修饰符和类型
    +
    方法
    +
    说明
    +
    void
    +
    RowGameModel.recordMove(int row, + int col, + Player player)
    +
    +
    Method to record a move in the move history stack.
    +
    +
    void
    +
    RowGameModel.setPlayer(Player player)
    +
     
    +
    +
    参数类型为Playermodel中的构造器
    +
    +
    限定符
    +
    构造器
    +
    说明
    +
     
    +
    Move(int row, + int col, + Player player)
    +
     
    +
    +
    +
  • +
+
+
+
+
+ + diff --git a/tictactoe/jdoc/model/class-use/RowBlockModel.html b/tictactoe/jdoc/model/class-use/RowBlockModel.html new file mode 100644 index 00000000..c728576b --- /dev/null +++ b/tictactoe/jdoc/model/class-use/RowBlockModel.html @@ -0,0 +1,83 @@ + + + + +类 model.RowBlockModel的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

类的使用
model.RowBlockModel

+
+
使用RowBlockModel的程序包
+
+
程序包
+
说明
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/model/class-use/RowGameModel.Move.html b/tictactoe/jdoc/model/class-use/RowGameModel.Move.html new file mode 100644 index 00000000..11cd4d08 --- /dev/null +++ b/tictactoe/jdoc/model/class-use/RowGameModel.Move.html @@ -0,0 +1,83 @@ + + + + +类 model.RowGameModel.Move的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

类的使用
model.RowGameModel.Move

+
+
使用RowGameModel.Move的程序包
+
+
程序包
+
说明
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/model/class-use/RowGameModel.html b/tictactoe/jdoc/model/class-use/RowGameModel.html new file mode 100644 index 00000000..f4db7b4d --- /dev/null +++ b/tictactoe/jdoc/model/class-use/RowGameModel.html @@ -0,0 +1,163 @@ + + + + +类 model.RowGameModel的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

类的使用
model.RowGameModel

+
+
使用RowGameModel的程序包
+
+
程序包
+
说明
+ +
 
+ +
 
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/model/package-summary.html b/tictactoe/jdoc/model/package-summary.html new file mode 100644 index 00000000..b5a6528f --- /dev/null +++ b/tictactoe/jdoc/model/package-summary.html @@ -0,0 +1,99 @@ + + + + +model (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包 model

+
+
+
package model
+
+
    +
  • +
    +
    +
    +
    +
    +
    说明
    + +
     
    + +
    +
    The TicTacToeBlock class represents a given block in the game.
    +
    + +
     
    + +
    +
    Inner class to represent a move made by a player.
    +
    +
    +
    +
    +
  • +
+
+
+
+
+ + diff --git a/tictactoe/jdoc/model/package-tree.html b/tictactoe/jdoc/model/package-tree.html new file mode 100644 index 00000000..c8953070 --- /dev/null +++ b/tictactoe/jdoc/model/package-tree.html @@ -0,0 +1,88 @@ + + + + +model 类分层结构 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包model的分层结构

+程序包分层结构: + +
+
+

类分层结构

+ +
+
+

Enum Class Hierarchy

+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/model/package-use.html b/tictactoe/jdoc/model/package-use.html new file mode 100644 index 00000000..5c17ba30 --- /dev/null +++ b/tictactoe/jdoc/model/package-use.html @@ -0,0 +1,116 @@ + + + + +程序包 model的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包的使用
model

+
+
使用model的程序包
+
+
程序包
+
说明
+ +
 
+ +
 
+ +
 
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/module-search-index.js b/tictactoe/jdoc/module-search-index.js new file mode 100644 index 00000000..0d59754f --- /dev/null +++ b/tictactoe/jdoc/module-search-index.js @@ -0,0 +1 @@ +moduleSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/tictactoe/jdoc/overview-summary.html b/tictactoe/jdoc/overview-summary.html new file mode 100644 index 00000000..5b201487 --- /dev/null +++ b/tictactoe/jdoc/overview-summary.html @@ -0,0 +1,26 @@ + + + + +CS520 - Homework 1 + + + + + + + + + + + +
+ +

index.html

+
+ + diff --git a/tictactoe/jdoc/overview-tree.html b/tictactoe/jdoc/overview-tree.html new file mode 100644 index 00000000..5150d630 --- /dev/null +++ b/tictactoe/jdoc/overview-tree.html @@ -0,0 +1,102 @@ + + + + +类分层结构 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

所有程序包的分层结构

+程序包分层结构: + +
+
+

类分层结构

+ +
+
+

接口分层结构

+ +
+
+

Enum Class Hierarchy

+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/package-search-index.js b/tictactoe/jdoc/package-search-index.js new file mode 100644 index 00000000..5dd0f850 --- /dev/null +++ b/tictactoe/jdoc/package-search-index.js @@ -0,0 +1 @@ +packageSearchIndex = [{"l":"controller"},{"l":"model"},{"l":"view"},{"l":"所有程序包","u":"allpackages-index.html"}];updateSearchResults(); \ No newline at end of file diff --git a/tictactoe/jdoc/package-summary.html b/tictactoe/jdoc/package-summary.html new file mode 100644 index 00000000..16d7aa67 --- /dev/null +++ b/tictactoe/jdoc/package-summary.html @@ -0,0 +1,82 @@ + + + + +Unnamed Package (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

Unnamed Package

+
+
+
+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/package-tree.html b/tictactoe/jdoc/package-tree.html new file mode 100644 index 00000000..c5df6cd6 --- /dev/null +++ b/tictactoe/jdoc/package-tree.html @@ -0,0 +1,72 @@ + + + + + 类分层结构 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

Hierarchy For Unnamed Package

+程序包分层结构: + +
+
+

类分层结构

+ +
+
+
+
+ + diff --git a/tictactoe/jdoc/package-use.html b/tictactoe/jdoc/package-use.html new file mode 100644 index 00000000..53807ff5 --- /dev/null +++ b/tictactoe/jdoc/package-use.html @@ -0,0 +1,58 @@ + + + + +程序包 的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
+ +
+
+
+

程序包的使用

+
+没有Unnamed Package的用法
+
+
+ + diff --git a/tictactoe/jdoc/resources/glass.png b/tictactoe/jdoc/resources/glass.png new file mode 100644 index 00000000..a7f591f4 Binary files /dev/null and b/tictactoe/jdoc/resources/glass.png differ diff --git a/tictactoe/jdoc/resources/x.png b/tictactoe/jdoc/resources/x.png new file mode 100644 index 00000000..30548a75 Binary files /dev/null and b/tictactoe/jdoc/resources/x.png differ diff --git a/tictactoe/jdoc/script-dir/jquery-3.6.0.min.js b/tictactoe/jdoc/script-dir/jquery-3.6.0.min.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/tictactoe/jdoc/script-dir/jquery-3.6.0.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,l=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
    ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
    ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("
    ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
    ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});x.ui.autocomplete}); \ No newline at end of file diff --git a/tictactoe/jdoc/script.js b/tictactoe/jdoc/script.js new file mode 100644 index 00000000..0765364e --- /dev/null +++ b/tictactoe/jdoc/script.js @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +var moduleSearchIndex; +var packageSearchIndex; +var typeSearchIndex; +var memberSearchIndex; +var tagSearchIndex; +function loadScripts(doc, tag) { + createElem(doc, tag, 'search.js'); + + createElem(doc, tag, 'module-search-index.js'); + createElem(doc, tag, 'package-search-index.js'); + createElem(doc, tag, 'type-search-index.js'); + createElem(doc, tag, 'member-search-index.js'); + createElem(doc, tag, 'tag-search-index.js'); +} + +function createElem(doc, tag, path) { + var script = doc.createElement(tag); + var scriptElement = doc.getElementsByTagName(tag)[0]; + script.src = pathtoroot + path; + scriptElement.parentNode.insertBefore(script, scriptElement); +} + +function show(tableId, selected, columns) { + if (tableId !== selected) { + document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') + .forEach(function(elem) { + elem.style.display = 'none'; + }); + } + document.querySelectorAll('div.' + selected) + .forEach(function(elem, index) { + elem.style.display = ''; + var isEvenRow = index % (columns * 2) < columns; + elem.classList.remove(isEvenRow ? oddRowColor : evenRowColor); + elem.classList.add(isEvenRow ? evenRowColor : oddRowColor); + }); + updateTabs(tableId, selected); +} + +function updateTabs(tableId, selected) { + document.querySelector('div#' + tableId +' .summary-table') + .setAttribute('aria-labelledby', selected); + document.querySelectorAll('button[id^="' + tableId + '"]') + .forEach(function(tab, index) { + if (selected === tab.id || (tableId === selected && index === 0)) { + tab.className = activeTableTab; + tab.setAttribute('aria-selected', true); + tab.setAttribute('tabindex',0); + } else { + tab.className = tableTab; + tab.setAttribute('aria-selected', false); + tab.setAttribute('tabindex',-1); + } + }); +} + +function switchTab(e) { + var selected = document.querySelector('[aria-selected=true]'); + if (selected) { + if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { + // left or up arrow key pressed: move focus to previous tab + selected.previousSibling.click(); + selected.previousSibling.focus(); + e.preventDefault(); + } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { + // right or down arrow key pressed: move focus to next tab + selected.nextSibling.click(); + selected.nextSibling.focus(); + e.preventDefault(); + } + } +} + +var updateSearchResults = function() {}; + +function indexFilesLoaded() { + return moduleSearchIndex + && packageSearchIndex + && typeSearchIndex + && memberSearchIndex + && tagSearchIndex; +} + +// Workaround for scroll position not being included in browser history (8249133) +document.addEventListener("DOMContentLoaded", function(e) { + var contentDiv = document.querySelector("div.flex-content"); + window.addEventListener("popstate", function(e) { + if (e.state !== null) { + contentDiv.scrollTop = e.state; + } + }); + window.addEventListener("hashchange", function(e) { + history.replaceState(contentDiv.scrollTop, document.title); + }); + contentDiv.addEventListener("scroll", function(e) { + var timeoutID; + if (!timeoutID) { + timeoutID = setTimeout(function() { + history.replaceState(contentDiv.scrollTop, document.title); + timeoutID = null; + }, 100); + } + }); + if (!location.hash) { + history.replaceState(contentDiv.scrollTop, document.title); + } +}); diff --git a/tictactoe/jdoc/search.js b/tictactoe/jdoc/search.js new file mode 100644 index 00000000..13aba853 --- /dev/null +++ b/tictactoe/jdoc/search.js @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +var noResult = {l: "No results found"}; +var loading = {l: "Loading search index..."}; +var catModules = "Modules"; +var catPackages = "Packages"; +var catTypes = "Classes and Interfaces"; +var catMembers = "Members"; +var catSearchTags = "Search Tags"; +var highlight = "$&"; +var searchPattern = ""; +var fallbackPattern = ""; +var RANKING_THRESHOLD = 2; +var NO_MATCH = 0xffff; +var MIN_RESULTS = 3; +var MAX_RESULTS = 500; +var UNNAMED = ""; +function escapeHtml(str) { + return str.replace(//g, ">"); +} +function getHighlightedText(item, matcher, fallbackMatcher) { + var escapedItem = escapeHtml(item); + var highlighted = escapedItem.replace(matcher, highlight); + if (highlighted === escapedItem) { + highlighted = escapedItem.replace(fallbackMatcher, highlight) + } + return highlighted; +} +function getURLPrefix(ui) { + var urlPrefix=""; + var slash = "/"; + if (ui.item.category === catModules) { + return ui.item.l + slash; + } else if (ui.item.category === catPackages && ui.item.m) { + return ui.item.m + slash; + } else if (ui.item.category === catTypes || ui.item.category === catMembers) { + if (ui.item.m) { + urlPrefix = ui.item.m + slash; + } else { + $.each(packageSearchIndex, function(index, item) { + if (item.m && ui.item.p === item.l) { + urlPrefix = item.m + slash; + } + }); + } + } + return urlPrefix; +} +function createSearchPattern(term) { + var pattern = ""; + var isWordToken = false; + term.replace(/,\s*/g, ", ").trim().split(/\s+/).forEach(function(w, index) { + if (index > 0) { + // whitespace between identifiers is significant + pattern += (isWordToken && /^\w/.test(w)) ? "\\s+" : "\\s*"; + } + var tokens = w.split(/(?=[A-Z,.()<>[\/])/); + for (var i = 0; i < tokens.length; i++) { + var s = tokens[i]; + if (s === "") { + continue; + } + pattern += $.ui.autocomplete.escapeRegex(s); + isWordToken = /\w$/.test(s); + if (isWordToken) { + pattern += "([a-z0-9_$<>\\[\\]]*?)"; + } + } + }); + return pattern; +} +function createMatcher(pattern, flags) { + var isCamelCase = /[A-Z]/.test(pattern); + return new RegExp(pattern, flags + (isCamelCase ? "" : "i")); +} +var watermark = 'Search'; +$(function() { + var search = $("#search-input"); + var reset = $("#reset-button"); + search.val(''); + search.prop("disabled", false); + reset.prop("disabled", false); + search.val(watermark).addClass('watermark'); + search.blur(function() { + if ($(this).val().length === 0) { + $(this).val(watermark).addClass('watermark'); + } + }); + search.on('click keydown paste', function() { + if ($(this).val() === watermark) { + $(this).val('').removeClass('watermark'); + } + }); + reset.click(function() { + search.val('').focus(); + }); + search.focus()[0].setSelectionRange(0, 0); +}); +$.widget("custom.catcomplete", $.ui.autocomplete, { + _create: function() { + this._super(); + this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); + }, + _renderMenu: function(ul, items) { + var rMenu = this; + var currentCategory = ""; + rMenu.menu.bindings = $(); + $.each(items, function(index, item) { + var li; + if (item.category && item.category !== currentCategory) { + ul.append("
  • " + item.category + "
  • "); + currentCategory = item.category; + } + li = rMenu._renderItemData(ul, item); + if (item.category) { + li.attr("aria-label", item.category + " : " + item.l); + li.attr("class", "result-item"); + } else { + li.attr("aria-label", item.l); + li.attr("class", "result-item"); + } + }); + }, + _renderItem: function(ul, item) { + var label = ""; + var matcher = createMatcher(escapeHtml(searchPattern), "g"); + var fallbackMatcher = new RegExp(fallbackPattern, "gi") + if (item.category === catModules) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catPackages) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catTypes) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catMembers) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.c + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.c + "." + item.l, matcher, fallbackMatcher); + } else if (item.category === catSearchTags) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else { + label = item.l; + } + var li = $("
  • ").appendTo(ul); + var div = $("
    ").appendTo(li); + if (item.category === catSearchTags && item.h) { + if (item.d) { + div.html(label + " (" + item.h + ")
    " + + item.d + "
    "); + } else { + div.html(label + " (" + item.h + ")"); + } + } else { + if (item.m) { + div.html(item.m + "/" + label); + } else { + div.html(label); + } + } + return li; + } +}); +function rankMatch(match, category) { + if (!match) { + return NO_MATCH; + } + var index = match.index; + var input = match.input; + var leftBoundaryMatch = 2; + var periferalMatch = 0; + // make sure match is anchored on a left word boundary + if (index === 0 || /\W/.test(input[index - 1]) || "_" === input[index]) { + leftBoundaryMatch = 0; + } else if ("_" === input[index - 1] || (input[index] === input[index].toUpperCase() && !/^[A-Z0-9_$]+$/.test(input))) { + leftBoundaryMatch = 1; + } + var matchEnd = index + match[0].length; + var leftParen = input.indexOf("("); + var endOfName = leftParen > -1 ? leftParen : input.length; + // exclude peripheral matches + if (category !== catModules && category !== catSearchTags) { + var delim = category === catPackages ? "/" : "."; + if (leftParen > -1 && leftParen < index) { + periferalMatch += 2; + } else if (input.lastIndexOf(delim, endOfName) >= matchEnd) { + periferalMatch += 2; + } + } + var delta = match[0].length === endOfName ? 0 : 1; // rank full match higher than partial match + for (var i = 1; i < match.length; i++) { + // lower ranking if parts of the name are missing + if (match[i]) + delta += match[i].length; + } + if (category === catTypes) { + // lower ranking if a type name contains unmatched camel-case parts + if (/[A-Z]/.test(input.substring(matchEnd))) + delta += 5; + if (/[A-Z]/.test(input.substring(0, index))) + delta += 5; + } + return leftBoundaryMatch + periferalMatch + (delta / 200); + +} +function doSearch(request, response) { + var result = []; + searchPattern = createSearchPattern(request.term); + fallbackPattern = createSearchPattern(request.term.toLowerCase()); + if (searchPattern === "") { + return this.close(); + } + var camelCaseMatcher = createMatcher(searchPattern, ""); + var fallbackMatcher = new RegExp(fallbackPattern, "i"); + + function searchIndexWithMatcher(indexArray, matcher, category, nameFunc) { + if (indexArray) { + var newResults = []; + $.each(indexArray, function (i, item) { + item.category = category; + var ranking = rankMatch(matcher.exec(nameFunc(item)), category); + if (ranking < RANKING_THRESHOLD) { + newResults.push({ranking: ranking, item: item}); + } + return newResults.length <= MAX_RESULTS; + }); + return newResults.sort(function(e1, e2) { + return e1.ranking - e2.ranking; + }).map(function(e) { + return e.item; + }); + } + return []; + } + function searchIndex(indexArray, category, nameFunc) { + var primaryResults = searchIndexWithMatcher(indexArray, camelCaseMatcher, category, nameFunc); + result = result.concat(primaryResults); + if (primaryResults.length <= MIN_RESULTS && !camelCaseMatcher.ignoreCase) { + var secondaryResults = searchIndexWithMatcher(indexArray, fallbackMatcher, category, nameFunc); + result = result.concat(secondaryResults.filter(function (item) { + return primaryResults.indexOf(item) === -1; + })); + } + } + + searchIndex(moduleSearchIndex, catModules, function(item) { return item.l; }); + searchIndex(packageSearchIndex, catPackages, function(item) { + return (item.m && request.term.indexOf("/") > -1) + ? (item.m + "/" + item.l) : item.l; + }); + searchIndex(typeSearchIndex, catTypes, function(item) { + return request.term.indexOf(".") > -1 ? item.p + "." + item.l : item.l; + }); + searchIndex(memberSearchIndex, catMembers, function(item) { + return request.term.indexOf(".") > -1 + ? item.p + "." + item.c + "." + item.l : item.l; + }); + searchIndex(tagSearchIndex, catSearchTags, function(item) { return item.l; }); + + if (!indexFilesLoaded()) { + updateSearchResults = function() { + doSearch(request, response); + } + result.unshift(loading); + } else { + updateSearchResults = function() {}; + } + response(result); +} +$(function() { + $("#search-input").catcomplete({ + minLength: 1, + delay: 300, + source: doSearch, + response: function(event, ui) { + if (!ui.content.length) { + ui.content.push(noResult); + } else { + $("#search-input").empty(); + } + }, + autoFocus: true, + focus: function(event, ui) { + return false; + }, + position: { + collision: "flip" + }, + select: function(event, ui) { + if (ui.item.category) { + var url = getURLPrefix(ui); + if (ui.item.category === catModules) { + url += "module-summary.html"; + } else if (ui.item.category === catPackages) { + if (ui.item.u) { + url = ui.item.u; + } else { + url += ui.item.l.replace(/\./g, '/') + "/package-summary.html"; + } + } else if (ui.item.category === catTypes) { + if (ui.item.u) { + url = ui.item.u; + } else if (ui.item.p === UNNAMED) { + url += ui.item.l + ".html"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html"; + } + } else if (ui.item.category === catMembers) { + if (ui.item.p === UNNAMED) { + url += ui.item.c + ".html" + "#"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#"; + } + if (ui.item.u) { + url += ui.item.u; + } else { + url += ui.item.l; + } + } else if (ui.item.category === catSearchTags) { + url += ui.item.u; + } + if (top !== window) { + parent.classFrame.location = pathtoroot + url; + } else { + window.location.href = pathtoroot + url; + } + $("#search-input").focus(); + } + } + }); +}); diff --git a/tictactoe/jdoc/stylesheet.css b/tictactoe/jdoc/stylesheet.css new file mode 100644 index 00000000..6dc5b365 --- /dev/null +++ b/tictactoe/jdoc/stylesheet.css @@ -0,0 +1,866 @@ +/* + * Javadoc style sheet + */ + +@import url('resources/fonts/dejavu.css'); + +/* + * Styles for individual HTML elements. + * + * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular + * HTML element throughout the page. + */ + +body { + background-color:#ffffff; + color:#353833; + font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:14px; + margin:0; + padding:0; + height:100%; + width:100%; +} +iframe { + margin:0; + padding:0; + height:100%; + width:100%; + overflow-y:scroll; + border:none; +} +a:link, a:visited { + text-decoration:none; + color:#4A6782; +} +a[href]:hover, a[href]:focus { + text-decoration:none; + color:#bb7a2a; +} +a[name] { + color:#353833; +} +pre { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; +} +h1 { + font-size:20px; +} +h2 { + font-size:18px; +} +h3 { + font-size:16px; +} +h4 { + font-size:15px; +} +h5 { + font-size:14px; +} +h6 { + font-size:13px; +} +ul { + list-style-type:disc; +} +code, tt { + font-family:'DejaVu Sans Mono', monospace; +} +:not(h1, h2, h3, h4, h5, h6) > code, +:not(h1, h2, h3, h4, h5, h6) > tt { + font-size:14px; + padding-top:4px; + margin-top:8px; + line-height:1.4em; +} +dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; +} +.summary-table dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + vertical-align:top; + padding-top:4px; +} +sup { + font-size:8px; +} +button { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size: 14px; +} +/* + * Styles for HTML generated by javadoc. + * + * These are style classes that are used by the standard doclet to generate HTML documentation. + */ + +/* + * Styles for document title and copyright. + */ +.clear { + clear:both; + height:0; + overflow:hidden; +} +.about-language { + float:right; + padding:0 21px 8px 8px; + font-size:11px; + margin-top:-9px; + height:2.9em; +} +.legal-copy { + margin-left:.5em; +} +.tab { + background-color:#0066FF; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* + * Styles for navigation bar. + */ +@media screen { + .flex-box { + position:fixed; + display:flex; + flex-direction:column; + height: 100%; + width: 100%; + } + .flex-header { + flex: 0 0 auto; + } + .flex-content { + flex: 1 1 auto; + overflow-y: auto; + } +} +.top-nav { + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + min-height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.sub-nav { + background-color:#dee3e9; + float:left; + width:100%; + overflow:hidden; + font-size:12px; +} +.sub-nav div { + clear:left; + float:left; + padding:0 0 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list { + padding-top:5px; +} +ul.nav-list { + display:block; + margin:0 25px 0 0; + padding:0; +} +ul.sub-nav-list { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.nav-list li { + list-style:none; + float:left; + padding: 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list-search { + float:right; + margin:0 0 0 0; + padding:5px 6px; + clear:none; +} +.nav-list-search label { + position:relative; + right:-16px; +} +ul.sub-nav-list li { + list-style:none; + float:left; + padding-top:10px; +} +.top-nav a:link, .top-nav a:active, .top-nav a:visited { + color:#FFFFFF; + text-decoration:none; + text-transform:uppercase; +} +.top-nav a:hover { + text-decoration:none; + color:#bb7a2a; + text-transform:uppercase; +} +.nav-bar-cell1-rev { + background-color:#F8981D; + color:#253441; + margin: auto 5px; +} +.skip-nav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* + * Hide navigation links and search box in print layout + */ +@media print { + ul.nav-list, div.sub-nav { + display:none; + } +} +/* + * Styles for page header and footer. + */ +.title { + color:#2c4557; + margin:10px 0; +} +.sub-title { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 15px 0; + padding:0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:13px; +} +/* + * Styles for headings. + */ +body.class-declaration-page .summary h2, +body.class-declaration-page .details h2, +body.class-use-page h2, +body.module-declaration-page .block-list h2 { + font-style: italic; + padding:0; + margin:15px 0; +} +body.class-declaration-page .summary h3, +body.class-declaration-page .details h3, +body.class-declaration-page .summary .inherited-list h2 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +/* + * Styles for page layout containers. + */ +main { + clear:both; + padding:10px 20px; + position:relative; +} +dl.notes > dt { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:12px; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +dl.notes > dd { + margin:5px 10px 10px 0; + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +dl.name-value > dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +dl.name-value > dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* + * Styles for lists. + */ +li.circle { + list-style:circle; +} +ul.horizontal li { + display:inline; + font-size:0.9em; +} +div.inheritance { + margin:0; + padding:0; +} +div.inheritance div.inheritance { + margin-left:2em; +} +ul.block-list, +ul.details-list, +ul.member-list, +ul.summary-list { + margin:10px 0 10px 0; + padding:0; +} +ul.block-list > li, +ul.details-list > li, +ul.member-list > li, +ul.summary-list > li { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +.summary-table dl, .summary-table dl dt, .summary-table dl dd { + margin-top:0; + margin-bottom:1px; +} +ul.see-list, ul.see-list-long { + padding-left: 0; + list-style: none; +} +ul.see-list li { + display: inline; +} +ul.see-list li:not(:last-child):after, +ul.see-list-long li:not(:last-child):after { + content: ", "; + white-space: pre-wrap; +} +/* + * Styles for tables. + */ +.summary-table, .details-table { + width:100%; + border-spacing:0; + border-left:1px solid #EEE; + border-right:1px solid #EEE; + border-bottom:1px solid #EEE; + padding:0; +} +.caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#253441; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0; + padding-top:10px; + padding-left:1px; + margin:0; + white-space:pre; +} +.caption a:link, .caption a:visited { + color:#1f389c; +} +.caption a:hover, +.caption a:active { + color:#FFFFFF; +} +.caption span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + padding-bottom:7px; + display:inline-block; + float:left; + background-color:#F8981D; + border: none; + height:16px; +} +div.table-tabs { + padding:10px 0 0 1px; + margin:0; +} +div.table-tabs > button { + border: none; + cursor: pointer; + padding: 5px 12px 7px 12px; + font-weight: bold; + margin-right: 3px; +} +div.table-tabs > button.active-table-tab { + background: #F8981D; + color: #253441; +} +div.table-tabs > button.table-tab { + background: #4D7A97; + color: #FFFFFF; +} +.two-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); +} +.three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, auto); +} +.four-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(10%, max-content) minmax(10%, max-content) minmax(10%, auto); +} +@media screen and (max-width: 600px) { + .two-column-summary { + display: grid; + grid-template-columns: 1fr; + } +} +@media screen and (max-width: 800px) { + .three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(25%, auto); + } + .three-column-summary .col-last { + grid-column-end: span 2; + } +} +@media screen and (max-width: 1000px) { + .four-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); + } +} +.summary-table > div, .details-table > div { + text-align:left; + padding: 8px 3px 3px 7px; +} +.col-first, .col-second, .col-last, .col-constructor-name, .col-summary-item-name { + vertical-align:top; + padding-right:0; + padding-top:8px; + padding-bottom:3px; +} +.table-header { + background:#dee3e9; + font-weight: bold; +} +.col-first, .col-first { + font-size:13px; +} +.col-second, .col-second, .col-last, .col-constructor-name, .col-summary-item-name, .col-last { + font-size:13px; +} +.col-first, .col-second, .col-constructor-name { + vertical-align:top; + overflow: auto; +} +.col-last { + white-space:normal; +} +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-constructor-name a:link, .col-constructor-name a:visited, +.col-summary-item-name a:link, .col-summary-item-name a:visited, +.constant-values-container a:link, .constant-values-container a:visited, +.all-classes-container a:link, .all-classes-container a:visited, +.all-packages-container a:link, .all-packages-container a:visited { + font-weight:bold; +} +.table-sub-heading-color { + background-color:#EEEEFF; +} +.even-row-color, .even-row-color .table-header { + background-color:#FFFFFF; +} +.odd-row-color, .odd-row-color .table-header { + background-color:#EEEEEF; +} +/* + * Styles for contents. + */ +.deprecated-content { + margin:0; + padding:10px 0; +} +div.block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +.col-last div { + padding-top:0; +} +.col-last a { + padding-bottom:3px; +} +.module-signature, +.package-signature, +.type-signature, +.member-signature { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + margin:14px 0; + white-space: pre-wrap; +} +.module-signature, +.package-signature, +.type-signature { + margin-top: 0; +} +.member-signature .type-parameters-long, +.member-signature .parameters, +.member-signature .exceptions { + display: inline-block; + vertical-align: top; + white-space: pre; +} +.member-signature .type-parameters { + white-space: normal; +} +/* + * Styles for formatting effect. + */ +.source-line-no { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:10px; +} +.block { + display:block; + margin:0 10px 5px 0; + color:#474747; +} +.deprecated-label, .descfrm-type-label, .implementation-label, .member-name-label, .member-name-link, +.module-label-in-package, .module-label-in-type, .override-specify-label, .package-label-in-type, +.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label { + font-weight:bold; +} +.deprecation-comment, .help-footnote, .preview-comment { + font-style:italic; +} +.deprecation-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +.preview-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +div.block div.deprecation-comment { + font-style:normal; +} +/* + * Styles specific to HTML5 elements. + */ +main, nav, header, footer, section { + display:block; +} +/* + * Styles for javadoc search. + */ +.ui-autocomplete-category { + font-weight:bold; + font-size:15px; + padding:7px 0 7px 3px; + background-color:#4D7A97; + color:#FFFFFF; +} +.ui-autocomplete { + max-height:85%; + max-width:65%; + overflow-y:scroll; + overflow-x:scroll; + white-space:nowrap; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); +} +ul.ui-autocomplete { + position:fixed; + z-index:999999; + background-color: #FFFFFF; +} +ul.ui-autocomplete li { + float:left; + clear:both; + width:100%; +} +.ui-autocomplete .result-item { + font-size: inherit; +} +.ui-autocomplete .result-highlight { + font-weight:bold; +} +#search-input { + background-image:url('resources/glass.png'); + background-size:13px; + background-repeat:no-repeat; + background-position:2px 3px; + padding-left:20px; + position:relative; + right:-18px; + width:400px; +} +#reset-button { + background-color: rgb(255,255,255); + background-image:url('resources/x.png'); + background-position:center; + background-repeat:no-repeat; + background-size:12px; + border:0 none; + width:16px; + height:16px; + position:relative; + left:-4px; + top:-4px; + font-size:0px; +} +.watermark { + color:#545454; +} +.search-tag-desc-result { + font-style:italic; + font-size:11px; +} +.search-tag-holder-result { + font-style:italic; + font-size:12px; +} +.search-tag-result:target { + background-color:yellow; +} +.module-graph span { + display:none; + position:absolute; +} +.module-graph:hover span { + display:block; + margin: -100px 0 0 100px; + z-index: 1; +} +.inherited-list { + margin: 10px 0 10px 0; +} +section.class-description { + line-height: 1.4; +} +.summary section[class$="-summary"], .details section[class$="-details"], +.class-uses .detail, .serialized-class-details { + padding: 0px 20px 5px 10px; + border: 1px solid #ededed; + background-color: #f8f8f8; +} +.inherited-list, section[class$="-details"] .detail { + padding:0 0 5px 8px; + background-color:#ffffff; + border:none; +} +.vertical-separator { + padding: 0 5px; +} +ul.help-section-list { + margin: 0; +} +ul.help-subtoc > li { + display: inline-block; + padding-right: 5px; + font-size: smaller; +} +ul.help-subtoc > li::before { + content: "\2022" ; + padding-right:2px; +} +span.help-note { + font-style: italic; +} +/* + * Indicator icon for external links. + */ +main a[href*="://"]::after { + content:""; + display:inline-block; + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); + background-size:100% 100%; + width:7px; + height:7px; + margin-left:2px; + margin-bottom:4px; +} +main a[href*="://"]:hover::after, +main a[href*="://"]:focus::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); +} + +/* + * Styles for user-provided tables. + * + * borderless: + * No borders, vertical margins, styled caption. + * This style is provided for use with existing doc comments. + * In general, borderless tables should not be used for layout purposes. + * + * plain: + * Plain borders around table and cells, vertical margins, styled caption. + * Best for small tables or for complex tables for tables with cells that span + * rows and columns, when the "striped" style does not work well. + * + * striped: + * Borders around the table and vertical borders between cells, striped rows, + * vertical margins, styled caption. + * Best for tables that have a header row, and a body containing a series of simple rows. + */ + +table.borderless, +table.plain, +table.striped { + margin-top: 10px; + margin-bottom: 10px; +} +table.borderless > caption, +table.plain > caption, +table.striped > caption { + font-weight: bold; + font-size: smaller; +} +table.borderless th, table.borderless td, +table.plain th, table.plain td, +table.striped th, table.striped td { + padding: 2px 5px; +} +table.borderless, +table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, +table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { + border: none; +} +table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { + background-color: transparent; +} +table.plain { + border-collapse: collapse; + border: 1px solid black; +} +table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { + background-color: transparent; +} +table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, +table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { + border: 1px solid black; +} +table.striped { + border-collapse: collapse; + border: 1px solid black; +} +table.striped > thead { + background-color: #E3E3E3; +} +table.striped > thead > tr > th, table.striped > thead > tr > td { + border: 1px solid black; +} +table.striped > tbody > tr:nth-child(even) { + background-color: #EEE +} +table.striped > tbody > tr:nth-child(odd) { + background-color: #FFF +} +table.striped > tbody > tr > th, table.striped > tbody > tr > td { + border-left: 1px solid black; + border-right: 1px solid black; +} +table.striped > tbody > tr > th { + font-weight: normal; +} +/** + * Tweak font sizes and paddings for small screens. + */ +@media screen and (max-width: 1050px) { + #search-input { + width: 300px; + } +} +@media screen and (max-width: 800px) { + #search-input { + width: 200px; + } + .top-nav, + .bottom-nav { + font-size: 11px; + padding-top: 6px; + } + .sub-nav { + font-size: 11px; + } + .about-language { + padding-right: 16px; + } + ul.nav-list li, + .sub-nav .nav-list-search { + padding: 6px; + } + ul.sub-nav-list li { + padding-top: 5px; + } + main { + padding: 10px; + } + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0 8px 5px 8px; + } + body { + -webkit-text-size-adjust: none; + } +} +@media screen and (max-width: 500px) { + #search-input { + width: 150px; + } + .top-nav, + .bottom-nav { + font-size: 10px; + } + .sub-nav { + font-size: 10px; + } + .about-language { + font-size: 10px; + padding-right: 12px; + } +} diff --git a/tictactoe/jdoc/tag-search-index.js b/tictactoe/jdoc/tag-search-index.js new file mode 100644 index 00000000..9f5ca6e5 --- /dev/null +++ b/tictactoe/jdoc/tag-search-index.js @@ -0,0 +1 @@ +tagSearchIndex = [{"l":"常量字段值","h":"","u":"constant-values.html"}];updateSearchResults(); \ No newline at end of file diff --git a/tictactoe/jdoc/type-search-index.js b/tictactoe/jdoc/type-search-index.js new file mode 100644 index 00000000..1ab98559 --- /dev/null +++ b/tictactoe/jdoc/type-search-index.js @@ -0,0 +1 @@ +typeSearchIndex = [{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"view","l":"BlockIndex"},{"p":"view","l":"GameBoardView"},{"p":"view","l":"GameStatusView"},{"p":"model","l":"RowGameModel.Move"},{"p":"model","l":"Player"},{"p":"model","l":"RowBlockModel"},{"p":"","l":"RowGameApp"},{"p":"controller","l":"RowGameController"},{"p":"view","l":"RowGameGUI"},{"p":"model","l":"RowGameModel"},{"p":"view","l":"View"}];updateSearchResults(); \ No newline at end of file diff --git a/tictactoe/jdoc/view/BlockIndex.html b/tictactoe/jdoc/view/BlockIndex.html new file mode 100644 index 00000000..f459d2d8 --- /dev/null +++ b/tictactoe/jdoc/view/BlockIndex.html @@ -0,0 +1,219 @@ + + + + +BlockIndex (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    程序包 view
    +

    类 BlockIndex

    +
    +
    java.lang.Object +
    view.BlockIndex
    +
    +
    +
    +
    public class BlockIndex +extends Object
    +
    +
    + +
    +
    +
      + +
    • +
      +

      字段详细资料

      +
        +
      • +
        +

        row

        +
        private final int row
        +
        +
      • +
      • +
        +

        column

        +
        private final int column
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      构造器详细资料

      +
        +
      • +
        +

        BlockIndex

        +
        public BlockIndex(int row, + int column)
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      方法详细资料

      +
        +
      • +
        +

        getRow

        +
        public int getRow()
        +
        +
      • +
      • +
        +

        getColumn

        +
        public int getColumn()
        +
        +
      • +
      • +
        +

        matches

        +
        public boolean matches(int row, + int column)
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/GameBoardView.html b/tictactoe/jdoc/view/GameBoardView.html new file mode 100644 index 00000000..c4b496fd --- /dev/null +++ b/tictactoe/jdoc/view/GameBoardView.html @@ -0,0 +1,248 @@ + + + + +GameBoardView (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    程序包 view
    +

    类 GameBoardView

    +
    +
    java.lang.Object +
    view.GameBoardView
    +
    +
    +
    +
    所有已实现的接口:
    +
    View
    +
    +
    +
    public class GameBoardView +extends Object +implements View
    +
    The GameBoardView class visualizes the game board of blocks. + + NOTE) For the Composite design pattern, this class is-a Component (i.e. + View).
    +
    +
    + +
    +
    +
      + +
    • +
      +

      字段详细资料

      +
        +
      • +
        +

        blocks

        +
        public JButton[][] blocks
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      构造器详细资料

      + +
      +
    • + +
    • +
      +

      方法详细资料

      +
        +
      • +
        +

        getBlockIndex

        +
        public BlockIndex getBlockIndex(JButton block)
        +
        Returns the BlockIndex (pair of row and column) of the given block + if it is part of this game board and returns null otherwise.
        +
        +
        参数:
        +
        block - The block of interest
        +
        返回:
        +
        The BlockIndex (pair of row and column) of the given block + if it is part of this game board and null otherwise
        +
        +
        +
      • +
      • +
        +

        updateBlock

        +
        public void updateBlock(RowGameModel gameModel, + int row, + int column)
        +
        Updates the block at the given row and column + after one of the player's moves.
        +
        +
        参数:
        +
        gameModel - The RowGameModel containing the block
        +
        row - The row that contains the block
        +
        column - The column that contains the block
        +
        +
        +
      • +
      • +
        +

        update

        +
        public void update(RowGameModel model)
        +
        +
        指定者:
        +
        update 在接口中 View
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/GameStatusView.html b/tictactoe/jdoc/view/GameStatusView.html new file mode 100644 index 00000000..edac1698 --- /dev/null +++ b/tictactoe/jdoc/view/GameStatusView.html @@ -0,0 +1,201 @@ + + + + +GameStatusView (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    程序包 view
    +

    类 GameStatusView

    +
    +
    java.lang.Object +
    view.GameStatusView
    +
    +
    +
    +
    所有已实现的接口:
    +
    View
    +
    +
    +
    public class GameStatusView +extends Object +implements View
    +
    The GameStatusView class visualizes the game status as either in progress, + current player's turn, or finished, either win or tie. + + NOTE) For the Composite design pattern, this class is-a Component (i.e. View).
    +
    +
    + +
    +
    +
      + +
    • +
      +

      字段详细资料

      +
        +
      • +
        +

        playerturn

        +
        private JTextArea playerturn
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      构造器详细资料

      +
        +
      • +
        +

        GameStatusView

        +
        public GameStatusView(JPanel messages)
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      方法详细资料

      + +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/RowGameGUI.html b/tictactoe/jdoc/view/RowGameGUI.html new file mode 100644 index 00000000..b736b82f --- /dev/null +++ b/tictactoe/jdoc/view/RowGameGUI.html @@ -0,0 +1,268 @@ + + + + +RowGameGUI (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    程序包 view
    +

    类 RowGameGUI

    +
    +
    java.lang.Object +
    view.RowGameGUI
    +
    +
    +
    +
    所有已实现的接口:
    +
    View
    +
    +
    +
    public class RowGameGUI +extends Object +implements View
    +
    The RowGameGUI class is applying the Composite design pattern. + This class is the Composite. The class also is-a Component (i.e. View).
    +
    +
    + +
    +
    +
      + +
    • +
      +

      字段详细资料

      +
        +
      • +
        +

        gui

        +
        public JFrame gui
        +
        +
      • +
      • +
        +

        gameModel

        +
        public RowGameModel gameModel
        +
        +
      • +
      • +
        +

        gameBoardView

        +
        public GameBoardView gameBoardView
        +
        +
      • +
      • +
        +

        viewList

        +
        private List<View> viewList
        +
        For the Composite design pattern, the RowGameGUI is the Composite
        +
        +
      • +
      • +
        +

        reset

        +
        public JButton reset
        +
        +
      • +
      • +
        +

        undo

        +
        public JButton undo
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      构造器详细资料

      +
        +
      • +
        +

        RowGameGUI

        +
        public RowGameGUI(RowGameController controller)
        +
        Creates a new game initializing the GUI.
        +
        +
      • +
      +
      +
    • + +
    • +
      +

      方法详细资料

      +
        +
      • +
        +

        getBlockIndex

        +
        public BlockIndex getBlockIndex(JButton block)
        +
        +
      • +
      • +
        +

        addView

        +
        public void addView(View view)
        +
        +
      • +
      • +
        +

        update

        +
        public void update(RowGameModel model)
        +
        +
        指定者:
        +
        update 在接口中 View
        +
        +
        +
      • +
      +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/View.html b/tictactoe/jdoc/view/View.html new file mode 100644 index 00000000..ebc067af --- /dev/null +++ b/tictactoe/jdoc/view/View.html @@ -0,0 +1,132 @@ + + + + +View (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    程序包 view
    +

    接口 View

    +
    +
    +
    +
    所有已知实现类:
    +
    GameBoardView, GameStatusView, RowGameGUI
    +
    +
    +
    public interface View
    +
    The View interfaces supports updating the visualizations of the Model. + + NOTE) For the Composite design pattern, the View interface is the Component interface.
    +
    +
    +
      + +
    • +
      +

      方法概要

      +
      +
      +
      +
      +
      修饰符和类型
      +
      方法
      +
      说明
      +
      void
      + +
       
      +
      +
      +
      +
      +
    • +
    +
    +
    +
      + +
    • +
      +

      方法详细资料

      + +
      +
    • +
    +
    + +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/class-use/BlockIndex.html b/tictactoe/jdoc/view/class-use/BlockIndex.html new file mode 100644 index 00000000..baa3bb79 --- /dev/null +++ b/tictactoe/jdoc/view/class-use/BlockIndex.html @@ -0,0 +1,89 @@ + + + + +类 view.BlockIndex的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    类的使用
    view.BlockIndex

    +
    +
    使用BlockIndex的程序包
    +
    +
    程序包
    +
    说明
    + +
     
    +
    +
    + +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/class-use/GameBoardView.html b/tictactoe/jdoc/view/class-use/GameBoardView.html new file mode 100644 index 00000000..038928f3 --- /dev/null +++ b/tictactoe/jdoc/view/class-use/GameBoardView.html @@ -0,0 +1,83 @@ + + + + +类 view.GameBoardView的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    类的使用
    view.GameBoardView

    +
    +
    使用GameBoardView的程序包
    +
    +
    程序包
    +
    说明
    + +
     
    +
    +
    + +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/class-use/GameStatusView.html b/tictactoe/jdoc/view/class-use/GameStatusView.html new file mode 100644 index 00000000..2abc7026 --- /dev/null +++ b/tictactoe/jdoc/view/class-use/GameStatusView.html @@ -0,0 +1,58 @@ + + + + +类 view.GameStatusView的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    类的使用
    view.GameStatusView

    +
    +没有view.GameStatusView的用法
    +
    +
    + + diff --git a/tictactoe/jdoc/view/class-use/RowGameGUI.html b/tictactoe/jdoc/view/class-use/RowGameGUI.html new file mode 100644 index 00000000..51f52ed1 --- /dev/null +++ b/tictactoe/jdoc/view/class-use/RowGameGUI.html @@ -0,0 +1,83 @@ + + + + +类 view.RowGameGUI的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    类的使用
    view.RowGameGUI

    +
    +
    使用RowGameGUI的程序包
    +
    +
    程序包
    +
    说明
    + +
     
    +
    +
    + +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/class-use/View.html b/tictactoe/jdoc/view/class-use/View.html new file mode 100644 index 00000000..4a90a6fd --- /dev/null +++ b/tictactoe/jdoc/view/class-use/View.html @@ -0,0 +1,116 @@ + + + + +接口 view.View的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    接口的使用
    view.View

    +
    +
    使用View的程序包
    +
    +
    程序包
    +
    说明
    + +
     
    +
    +
    +
      +
    • +
      +

      viewView的使用

      +
      实现Viewview中的类
      +
      +
      修饰符和类型
      +
      +
      说明
      +
      class 
      + +
      +
      The GameBoardView class visualizes the game board of blocks.
      +
      +
      class 
      + +
      +
      The GameStatusView class visualizes the game status as either in progress, + current player's turn, or finished, either win or tie.
      +
      +
      class 
      + +
      +
      The RowGameGUI class is applying the Composite design pattern.
      +
      +
      +
      类型参数类型为Viewview中的字段
      +
      +
      修饰符和类型
      +
      字段
      +
      说明
      +
      private List<View>
      +
      RowGameGUI.viewList
      +
      +
      For the Composite design pattern, the RowGameGUI is the Composite
      +
      +
      +
      参数类型为Viewview中的方法
      +
      +
      修饰符和类型
      +
      方法
      +
      说明
      +
      void
      +
      RowGameGUI.addView(View view)
      +
       
      +
      +
      +
    • +
    +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/package-summary.html b/tictactoe/jdoc/view/package-summary.html new file mode 100644 index 00000000..bc7ecdd4 --- /dev/null +++ b/tictactoe/jdoc/view/package-summary.html @@ -0,0 +1,106 @@ + + + + +view (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    程序包 view

    +
    +
    +
    package view
    +
    +
      +
    • +
      +
      +
      +
      +
      +
      说明
      + +
       
      + +
      +
      The GameBoardView class visualizes the game board of blocks.
      +
      + +
      +
      The GameStatusView class visualizes the game status as either in progress, + current player's turn, or finished, either win or tie.
      +
      + +
      +
      The RowGameGUI class is applying the Composite design pattern.
      +
      + +
      +
      The View interfaces supports updating the visualizations of the Model.
      +
      +
      +
      +
      +
    • +
    +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/package-tree.html b/tictactoe/jdoc/view/package-tree.html new file mode 100644 index 00000000..683a5ddc --- /dev/null +++ b/tictactoe/jdoc/view/package-tree.html @@ -0,0 +1,81 @@ + + + + +view 类分层结构 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    程序包view的分层结构

    +程序包分层结构: + +
    +
    +

    类分层结构

    + +
    +
    +

    接口分层结构

    + +
    +
    +
    +
    + + diff --git a/tictactoe/jdoc/view/package-use.html b/tictactoe/jdoc/view/package-use.html new file mode 100644 index 00000000..26965e56 --- /dev/null +++ b/tictactoe/jdoc/view/package-use.html @@ -0,0 +1,103 @@ + + + + +程序包 view的使用 (CS520 - Homework 1) + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    程序包的使用
    view

    +
    +
    使用view的程序包
    +
    +
    程序包
    +
    说明
    + +
     
    + +
     
    +
    +
    +
      +
    • +
      +
      controller使用的view中的类
      +
      +
      +
      说明
      + +
      +
      The RowGameGUI class is applying the Composite design pattern.
      +
      +
      +
      +
    • +
    • +
      +
      view使用的view中的类
      +
      +
      +
      说明
      + +
       
      + +
      +
      The GameBoardView class visualizes the game board of blocks.
      +
      + +
      +
      The View interfaces supports updating the visualizations of the Model.
      +
      +
      +
      +
    • +
    +
    +
    +
    +
    + + diff --git a/tictactoe/src/controller/RowGameController.java b/tictactoe/src/controller/RowGameController.java index 84e6ee28..daad037b 100644 --- a/tictactoe/src/controller/RowGameController.java +++ b/tictactoe/src/controller/RowGameController.java @@ -13,373 +13,506 @@ import view.RowGameGUI; public class RowGameController { - public RowGameModel gameModel; - public RowGameGUI gameView; + public RowGameModel gameModel; + public RowGameGUI gameView; - /** - * Creates a new game initializing the GUI. - */ - public RowGameController() { - gameModel = new RowGameModel(); - gameView = new RowGameGUI(this); + // Add a new button to the GUI for undo functionality + private JButton undo = new JButton("Undo"); - for(int row = 0; row<3; row++) { - for(int column = 0; column<3 ;column++) { - gameModel.blocksData[row][column].setContents(""); - gameModel.blocksData[row][column].setIsLegalMove(true); - } - } + /** + * Creates a new game initializing the GUI. + */ + public RowGameController() { + gameModel = new RowGameModel(); + gameView = new RowGameGUI(this); + /////////////// + // add undo button to the GUI + // gameView.gui.add(undo, BorderLayout.SOUTH); - gameView.update(gameModel); - } + // add action listener to the undo button + // undo.addActionListener(new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // undoMove(); + // } + // }); + //////////////// + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { + gameModel.blocksData[row][column].setContents(""); + gameModel.blocksData[row][column].setIsLegalMove(true); + } + } - /** - * Moves the current player into the given block. - * - * @param block The block to be moved to by the current player - */ - public void move(JButton block) { - // The Controller first manipulates the Model. - gameModel.movesLeft--; + gameView.update(gameModel); + } - BlockIndex blockIndex = gameView.getBlockIndex(block); - if(gameModel.getPlayer().equals(Player.PLAYER_1)) { - // Check whether player 1 won - if(blockIndex.matches(0, 0)) { - gameModel.blocksData[0][0].setContents("X"); - gameModel.blocksData[0][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[2][0].getContents())) || - (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][2].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(0, 1)) { - gameModel.blocksData[0][1].setContents("X"); - gameModel.blocksData[0][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][1].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(0, 2)) { - gameModel.blocksData[0][2].setContents("X"); - gameModel.blocksData[0][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents())) || - (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][2].getContents()) && - gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 0)) { - gameModel.blocksData[1][0].setContents("X"); - gameModel.blocksData[1][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][2].getContents())) || - (gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 1)) { - gameModel.blocksData[1][1].setContents("X"); - gameModel.blocksData[1][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][2].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[2][1].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()) && - gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 2)) { - gameModel.blocksData[1][2].setContents("X"); - gameModel.blocksData[1][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents()) && - gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 0)) { - gameModel.blocksData[2][0].setContents("X"); - gameModel.blocksData[2][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][1].getContents()) && - gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents())) || - (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 1)) { - gameModel.blocksData[2][1].setContents("X"); - gameModel.blocksData[2][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents()) && - gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 2)) { - gameModel.blocksData[2][2].setContents("X"); - gameModel.blocksData[2][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_2); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[2][1].getContents()) && - gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents())) || - (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][2].getContents()) && - gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } - } else { - // Check whether player 2 won - if(blockIndex.matches(0, 0)) { - gameModel.blocksData[0][0].setContents("O"); - gameModel.blocksData[0][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[2][0].getContents())) || - (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][2].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(0, 1)) { - gameModel.blocksData[0][1].setContents("O"); - gameModel.blocksData[0][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][1].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(0, 2)) { - gameModel.blocksData[0][2].setContents("O"); - gameModel.blocksData[0][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents())) || - (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][2].getContents()) && - gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 0)) { - gameModel.blocksData[1][0].setContents("O"); - gameModel.blocksData[1][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][2].getContents())) || - (gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 1)) { - gameModel.blocksData[1][1].setContents("O"); - gameModel.blocksData[1][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][2].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()) && - gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[2][1].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && - gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()) && - gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(1, 2)) { - gameModel.blocksData[1][2].setContents("O"); - gameModel.blocksData[1][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents()) && - gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 0)) { - gameModel.blocksData[2][0].setContents("O"); - gameModel.blocksData[2][0].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][1].getContents()) && - gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][0].getContents()) && - gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents())) || - (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 1)) { - gameModel.blocksData[2][1].setContents("O"); - gameModel.blocksData[2][1].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents()) && - gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][2].getContents())) || - (gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } - } - } else if(blockIndex.matches(2, 2)) { - gameModel.blocksData[2][2].setContents("O"); - gameModel.blocksData[2][2].setIsLegalMove(false); - gameModel.setPlayer(Player.PLAYER_1); - if(gameModel.movesLeft<7) { - if((gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[2][1].getContents()) && - gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents())) || - (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][2].getContents()) && - gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents())) || - (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][1].getContents()) && - gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()))) { - gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); - endGame(); - } else if(gameModel.movesLeft==0) { - gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); - } + ////////////// + public void undoMove() { + if (gameModel.movesLeft == 9) { + + throw new IllegalStateException("Cannot undo before making a move"); + } else if (gameModel.movesLeft < 9) { + gameModel.undoMove(); // call the undoMove() method of the model + gameView.update(gameModel); // update the view with the new model state } - } } + ////////////// + + /** + * Moves the current player into the given block. + * + * @param block The block to be moved to by the current player + */ + public void move(JButton block) { + // The Controller first manipulates the Model. + gameModel.movesLeft--; - // The Controller then updates the View. - gameView.update(gameModel); - } + BlockIndex blockIndex = gameView.getBlockIndex(block); + if (gameModel.getPlayer().equals(Player.PLAYER_1)) { + // Check whether player 1 won + if (blockIndex.matches(0, 0)) { + gameModel.blocksData[0][0].setContents("X"); + gameModel.blocksData[0][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(0, 0, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][1].getContents()) && + gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][0].getContents()) + && + gameModel.blocksData[1][0].getContents() + .equals(gameModel.blocksData[2][0].getContents())) + || + (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][2].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(0, 1)) { + gameModel.blocksData[0][1].setContents("X"); + gameModel.blocksData[0][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(0, 1, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && + gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][1].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(0, 2)) { + gameModel.blocksData[0][2].setContents("X"); + gameModel.blocksData[0][2].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(0, 2, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[0][1].getContents()) && + gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents())) + || + (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][2].getContents()) + && + gameModel.blocksData[1][2].getContents() + .equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 0)) { + gameModel.blocksData[1][0].setContents("X"); + gameModel.blocksData[1][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(1, 0, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && + gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][2].getContents())) + || + (gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents()) + && + gameModel.blocksData[0][0].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 1)) { + gameModel.blocksData[1][1].setContents("X"); + gameModel.blocksData[1][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(1, 1, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()) && + gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][2].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()) + && + gameModel.blocksData[0][1].getContents() + .equals(gameModel.blocksData[2][1].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()) + && + gameModel.blocksData[0][0].getContents() + .equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()) + && + gameModel.blocksData[0][2].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 2)) { + gameModel.blocksData[1][2].setContents("X"); + gameModel.blocksData[1][2].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(1, 2, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents()) && + gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[1][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 0)) { + gameModel.blocksData[2][0].setContents("X"); + gameModel.blocksData[2][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(2, 0, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][1].getContents()) && + gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][0].getContents()) + && + gameModel.blocksData[1][0].getContents() + .equals(gameModel.blocksData[0][0].getContents())) + || + (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][2].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 1)) { + gameModel.blocksData[2][1].setContents("X"); + gameModel.blocksData[2][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(2, 1, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents()) && + gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][1].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 2)) { + gameModel.blocksData[2][2].setContents("X"); + gameModel.blocksData[2][2].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_2); + gameModel.recordMove(2, 2, Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[2][1].getContents()) && + gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents())) + || + (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][2].getContents()) + && + gameModel.blocksData[1][2].getContents() + .equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_1 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } + } else { + // Check whether player 2 won + if (blockIndex.matches(0, 0)) { + gameModel.blocksData[0][0].setContents("O"); + gameModel.blocksData[0][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(0, 0, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][1].getContents()) && + gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][0].getContents()) + && + gameModel.blocksData[1][0].getContents() + .equals(gameModel.blocksData[2][0].getContents())) + || + (gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][2].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(0, 1)) { + gameModel.blocksData[0][1].setContents("O"); + gameModel.blocksData[0][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(0, 1, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents()) && + gameModel.blocksData[0][0].getContents().equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][1].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(0, 2)) { + gameModel.blocksData[0][2].setContents("O"); + gameModel.blocksData[0][2].setIsLegalMove(false); + gameModel.recordMove(0, 2, Player.PLAYER_2); + gameModel.setPlayer(Player.PLAYER_1); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[0][1].getContents()) && + gameModel.blocksData[0][1].getContents().equals(gameModel.blocksData[0][0].getContents())) + || + (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][2].getContents()) + && + gameModel.blocksData[1][2].getContents() + .equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 0)) { + gameModel.blocksData[1][0].setContents("O"); + gameModel.blocksData[1][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(1, 0, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][1].getContents()) && + gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][2].getContents())) + || + (gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[0][0].getContents()) + && + gameModel.blocksData[0][0].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 1)) { + gameModel.blocksData[1][1].setContents("O"); + gameModel.blocksData[1][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(1, 1, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[1][0].getContents()) && + gameModel.blocksData[1][0].getContents().equals(gameModel.blocksData[1][2].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][1].getContents()) + && + gameModel.blocksData[0][1].getContents() + .equals(gameModel.blocksData[2][1].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][0].getContents()) + && + gameModel.blocksData[0][0].getContents() + .equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[1][1].getContents().equals(gameModel.blocksData[0][2].getContents()) + && + gameModel.blocksData[0][2].getContents() + .equals(gameModel.blocksData[2][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(1, 2)) { + gameModel.blocksData[1][2].setContents("O"); + gameModel.blocksData[1][2].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(1, 2, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[0][2].getContents()) && + gameModel.blocksData[0][2].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[1][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[1][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 0)) { + gameModel.blocksData[2][0].setContents("O"); + gameModel.blocksData[2][0].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(2, 0, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][1].getContents()) && + gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][0].getContents()) + && + gameModel.blocksData[1][0].getContents() + .equals(gameModel.blocksData[0][0].getContents())) + || + (gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][2].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 1)) { + gameModel.blocksData[2][1].setContents("O"); + gameModel.blocksData[2][1].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(2, 1, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents()) && + gameModel.blocksData[2][0].getContents().equals(gameModel.blocksData[2][2].getContents())) + || + (gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][1].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } else if (blockIndex.matches(2, 2)) { + gameModel.blocksData[2][2].setContents("O"); + gameModel.blocksData[2][2].setIsLegalMove(false); + gameModel.setPlayer(Player.PLAYER_1); + gameModel.recordMove(2, 2, Player.PLAYER_2); + if (gameModel.movesLeft < 7) { + if ((gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[2][1].getContents()) && + gameModel.blocksData[2][1].getContents().equals(gameModel.blocksData[2][0].getContents())) + || + (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][2].getContents()) + && + gameModel.blocksData[1][2].getContents() + .equals(gameModel.blocksData[0][2].getContents())) + || + (gameModel.blocksData[2][2].getContents().equals(gameModel.blocksData[1][1].getContents()) + && + gameModel.blocksData[1][1].getContents() + .equals(gameModel.blocksData[0][0].getContents()))) { + gameModel.setFinalResult("Player " + Player.PLAYER_2 + " wins!"); + endGame(); + } else if (gameModel.movesLeft == 0) { + gameModel.setFinalResult(RowGameModel.GAME_END_NOWINNER); + } + } + } + } - /** - * Ends the game disallowing further player turns. - */ - public void endGame() { - // The Controller first manipulates the Model. - for(int row = 0;row<3;row++) { - for(int column = 0;column<3;column++) { - gameModel.blocksData[row][column].setIsLegalMove(false); - } + // The Controller then updates the View. + gameView.update(gameModel); } - // The Controller then updates the View. - gameView.update(gameModel); - } + /** + * Ends the game disallowing further player turns. + */ + public void endGame() { + // The Controller first manipulates the Model. + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { + gameModel.blocksData[row][column].setIsLegalMove(false); + } + } - /** - * Resets the game to be able to start playing again. - */ - public void resetGame() { - // The Controller first manipulates the Model. - for(int row = 0;row<3;row++) { - for(int column = 0;column<3;column++) { - gameModel.blocksData[row][column].reset(); - gameModel.blocksData[row][column].setIsLegalMove(true); - } - } - gameModel.setPlayer(Player.PLAYER_1); - gameModel.movesLeft = 9; - gameModel.setFinalResult(null); + // The Controller then updates the View. + gameView.update(gameModel); + } - // The Controller then updates the View. - gameView.update(gameModel); - } + /** + * Resets the game to be able to start playing again. + */ + public void resetGame() { + // The Controller first manipulates the Model. + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { + gameModel.blocksData[row][column].reset(); + gameModel.blocksData[row][column].setIsLegalMove(true); + } + } + gameModel.setPlayer(Player.PLAYER_1); + gameModel.movesLeft = 9; + gameModel.setFinalResult(null); + + // The Controller then updates the View. + gameView.update(gameModel); + } } diff --git a/tictactoe/src/model/RowBlockModel.java b/tictactoe/src/model/RowBlockModel.java index f7029df1..672d251b 100644 --- a/tictactoe/src/model/RowBlockModel.java +++ b/tictactoe/src/model/RowBlockModel.java @@ -3,8 +3,7 @@ /** * The TicTacToeBlock class represents a given block in the game. */ -public class RowBlockModel -{ +public class RowBlockModel { /** * The game that contains this block */ @@ -27,18 +26,18 @@ public class RowBlockModel * @throws IllegalArgumentException When the given game is null */ public RowBlockModel(RowGameModel game) { - super(); + super(); - if (game == null) { - throw new IllegalArgumentException("The game must be non-null."); - } - - this.game = game; - this.reset(); + if (game == null) { + throw new IllegalArgumentException("The game must be non-null."); + } + + this.game = game; + this.reset(); } public RowGameModel getGame() { - return this.game; + return this.game; } /** @@ -48,10 +47,10 @@ public RowGameModel getGame() { * @throws IllegalArgumentException When the given value is null */ public void setContents(String value) { - if (value == null) { - throw new IllegalArgumentException("The value must be non-null."); - } - this.contents = value; + if (value == null) { + throw new IllegalArgumentException("The value must be non-null."); + } + this.contents = value; } /** @@ -60,22 +59,22 @@ public void setContents(String value) { * @return The non-null String value */ public String getContents() { - return this.contents; + return this.contents; } public void setIsLegalMove(boolean isLegalMove) { - this.isLegalMove = isLegalMove; + this.isLegalMove = isLegalMove; } public boolean getIsLegalMove() { - return this.isLegalMove; + return this.isLegalMove; } /** * Resets this block before starting a new game. */ public void reset() { - this.contents = ""; - this.isLegalMove = false; + this.contents = ""; + this.isLegalMove = false; } } diff --git a/tictactoe/src/model/RowGameModel.java b/tictactoe/src/model/RowGameModel.java index f9b15ec1..7c0bb325 100644 --- a/tictactoe/src/model/RowGameModel.java +++ b/tictactoe/src/model/RowGameModel.java @@ -1,8 +1,8 @@ package model; +import java.util.Stack; -public class RowGameModel -{ +public class RowGameModel { public static final String GAME_END_NOWINNER = "Game ends in a draw"; public RowBlockModel[][] blocksData = new RowBlockModel[3][3]; @@ -13,37 +13,98 @@ public class RowGameModel private Player player = Player.PLAYER_1; public int movesLeft = 9; - private String finalResult = null; + public String finalResult = null; + private Stack moveHistory = new Stack<>(); // Stack to store move history public RowGameModel() { - super(); + super(); - for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) { - blocksData[row][col] = new RowBlockModel(this); - } // end for col - } // end for row + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 3; col++) { + blocksData[row][col] = new RowBlockModel(this); + } // end for col + } // end for row } public Player getPlayer() { - return this.player; + return this.player; } public void setPlayer(Player player) { - // Perform input validation - if (player == null) { - throw new IllegalArgumentException("The player must be non-null."); - } + // Perform input validation + if (player == null) { + throw new IllegalArgumentException("The player must be non-null."); + } - this.player = player; + this.player = player; } - + public String getFinalResult() { - return this.finalResult; + return this.finalResult; } public void setFinalResult(String finalResult) { - this.finalResult = finalResult; + this.finalResult = finalResult; + } + + /** + * Method to handle undo functionality. Allows undoing the previous move if + * there + * are moves to undo. + */ + public void undoMove() { + if (!moveHistory.isEmpty()) { // Check if there are moves to undo + Move lastMove = moveHistory.pop(); // Pop the last move from the move history stack + int row = lastMove.getRow(); + int col = lastMove.getCol(); + Player player = lastMove.getPlayer(); + + // Undo the move by resetting the contents of the corresponding block + blocksData[row][col].reset(); + blocksData[row][col].setIsLegalMove(true); + + // Update the model state + this.player = player; + this.movesLeft++; + } + } + + /** + * Method to record a move in the move history stack. + * + * @param row The row index of the block where the move was made + * @param col The column index of the block where the move was made + * @param player The player who made the move + */ + public void recordMove(int row, int col, Player player) { + moveHistory.push(new Move(row, col, player)); + } + + /** + * Inner class to represent a move made by a player. + */ + private static class Move { + private int row; + private int col; + private Player player; + + public Move(int row, int col, Player player) { + this.row = row; + this.col = col; + this.player = player; + } + + public int getRow() { + return row; + } + + public int getCol() { + return col; + } + + public Player getPlayer() { + return player; + } } -} +} \ No newline at end of file diff --git a/tictactoe/src/view/GameBoardView.java b/tictactoe/src/view/GameBoardView.java index 44c17d67..875a1e6d 100644 --- a/tictactoe/src/view/GameBoardView.java +++ b/tictactoe/src/view/GameBoardView.java @@ -9,33 +9,31 @@ import javax.swing.JButton; import javax.swing.JPanel; - /** * The GameBoardView class visualizes the game board of blocks. * - * NOTE) For the Composite design pattern, this class is-a Component (i.e. View). + * NOTE) For the Composite design pattern, this class is-a Component (i.e. + * View). */ -public class GameBoardView implements View -{ - private JButton[][] blocks = new JButton[3][3]; +public class GameBoardView implements View { + public JButton[][] blocks = new JButton[3][3]; - public GameBoardView(JPanel game, RowGameController controller) { - super(); + super(); // Initialize a JButton for each cell of the 3x3 game board. - for(int row = 0; row<3; row++) { - for(int column = 0; column<3 ;column++) { + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { blocks[row][column] = new JButton(); - blocks[row][column].setPreferredSize(new Dimension(75,75)); + blocks[row][column].setPreferredSize(new Dimension(75, 75)); game.add(blocks[row][column]); blocks[row][column].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - controller.move((JButton)e.getSource()); + controller.move((JButton) e.getSource()); } }); } - } + } } /** @@ -47,37 +45,37 @@ public void actionPerformed(ActionEvent e) { * if it is part of this game board and null otherwise */ public BlockIndex getBlockIndex(JButton block) { - for (int row = 0; row < 3; row++) { - for (int column = 0; column < 3; column++) { - if (this.blocks[row][column] == block) { - // Found - return new BlockIndex(row, column); - } - } // end for column - } // end for row + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { + if (this.blocks[row][column] == block) { + // Found + return new BlockIndex(row, column); + } + } // end for column + } // end for row - // Not found - return null; + // Not found + return null; } - + /** - * Updates the block at the given row and column + * Updates the block at the given row and column * after one of the player's moves. * * @param gameModel The RowGameModel containing the block - * @param row The row that contains the block - * @param column The column that contains the block + * @param row The row that contains the block + * @param column The column that contains the block */ public void updateBlock(RowGameModel gameModel, int row, int column) { blocks[row][column].setText(gameModel.blocksData[row][column].getContents()); blocks[row][column].setEnabled(gameModel.blocksData[row][column].getIsLegalMove()); } - + public void update(RowGameModel model) { - for (int row = 0; row < 3; row++) { - for (int column = 0; column < 3; column++) { - updateBlock(model, row, column); - } // end for col - } // end for row + for (int row = 0; row < 3; row++) { + for (int column = 0; column < 3; column++) { + updateBlock(model, row, column); + } // end for col + } // end for row } } // end for GameBoardView diff --git a/tictactoe/src/view/RowGameGUI.java b/tictactoe/src/view/RowGameGUI.java index b9716d55..60fce794 100644 --- a/tictactoe/src/view/RowGameGUI.java +++ b/tictactoe/src/view/RowGameGUI.java @@ -19,11 +19,12 @@ public class RowGameGUI implements View { public JFrame gui = new JFrame("Tic Tac Toe"); public RowGameModel gameModel = new RowGameModel(); - private GameBoardView gameBoardView; + public GameBoardView gameBoardView; /** For the Composite design pattern, the RowGameGUI is the Composite */ private List viewList = new ArrayList(); public JButton reset = new JButton("Reset"); - + // Add a new button to the GUI for undo functionality + public JButton undo = new JButton("Undo"); /** * Creates a new game initializing the GUI. @@ -34,11 +35,22 @@ public RowGameGUI(RowGameController controller) { gui.setResizable(true); JPanel gamePanel = new JPanel(new FlowLayout()); - JPanel game = new JPanel(new GridLayout(3,3)); + JPanel game = new JPanel(new GridLayout(3, 3)); gamePanel.add(game, BorderLayout.CENTER); JPanel options = new JPanel(new FlowLayout()); options.add(reset); + + // add the undo button to the options panel + options.add(undo); + + // add action listener to the undo button + undo.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + controller.undoMove(); + } + }); + JPanel messages = new JPanel(new FlowLayout()); messages.setBackground(Color.white); @@ -46,8 +58,8 @@ public RowGameGUI(RowGameController controller) { gui.add(options, BorderLayout.CENTER); gui.add(messages, BorderLayout.SOUTH); - GameStatusView gameStatusView = new GameStatusView(messages); - addView(gameStatusView); + GameStatusView gameStatusView = new GameStatusView(messages); + addView(gameStatusView); reset.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -55,30 +67,30 @@ public void actionPerformed(ActionEvent e) { } }); - this.gameBoardView = new GameBoardView(game, controller); - addView(this.gameBoardView); + this.gameBoardView = new GameBoardView(game, controller); + addView(this.gameBoardView); } public BlockIndex getBlockIndex(JButton block) { - return this.gameBoardView.getBlockIndex(block); + return this.gameBoardView.getBlockIndex(block); } public void addView(View view) { - // For the Composite API - - // Perform input validation - if (view == null) { - throw new IllegalArgumentException("The view must be non-null."); - } - - this.viewList.add(view); + // For the Composite API + + // Perform input validation + if (view == null) { + throw new IllegalArgumentException("The view must be non-null."); + } + + this.viewList.add(view); } public void update(RowGameModel model) { - // For the Composite API - - for (View currentView : this.viewList) { - currentView.update(model); - } // end for currentView + // For the Composite API + + for (View currentView : this.viewList) { + currentView.update(model); + } // end for currentView } -} +} \ No newline at end of file diff --git a/tictactoe/test/TestExample.java b/tictactoe/test/TestExample.java index f25efecc..d19bef1e 100644 --- a/tictactoe/test/TestExample.java +++ b/tictactoe/test/TestExample.java @@ -3,34 +3,130 @@ import org.junit.Test; import static org.junit.Assert.*; +import javax.swing.JButton; + import model.Player; import model.RowBlockModel; import controller.RowGameController; -/** - * An example test class, which merely shows how to write JUnit tests. - */ public class TestExample { private RowGameController game; @Before public void setUp() { - game = new RowGameController(); + game = new RowGameController(); } @After public void tearDown() { - game = null; + game = null; } @Test public void testNewGame() { - assertEquals (Player.PLAYER_1, game.gameModel.getPlayer()); - assertEquals (9, game.gameModel.movesLeft); + assertEquals(Player.PLAYER_1, game.gameModel.getPlayer()); + assertEquals(9, game.gameModel.movesLeft); } @Test(expected = IllegalArgumentException.class) public void testNewBlockViolatesPrecondition() { - RowBlockModel block = new RowBlockModel(null); + RowBlockModel block = new RowBlockModel(null); } + + @Test + public void testIllegalMove() { + // Make an illegal move (selecting an already occupied block) + // a legal move + game.move(game.gameView.gameBoardView.blocks[0][0]); + assertEquals(Player.PLAYER_2, game.gameModel.getPlayer()); + assertEquals(8, game.gameModel.movesLeft); + // an illegal move (selecting an already occupied block) + game.move(game.gameView.gameBoardView.blocks[0][0]); + assertEquals(Player.PLAYER_1, game.gameModel.getPlayer()); + assertEquals(7, game.gameModel.movesLeft); + } + + @Test + public void testLegalMoveUpdatesGame() { + + // Move to a valid block + game.move(game.gameView.gameBoardView.blocks[0][0]); + + // The current player should have changed + assertEquals(Player.PLAYER_2, game.gameModel.getPlayer()); + + // The blocks data should have been updated + assertEquals("X", game.gameModel.blocksData[0][0].getContents()); + + // The number of moves left should have decreased by 1 + assertEquals(8, game.gameModel.movesLeft); + } + + @Test + public void testWinningMove() { + // Player 1 makes the winning move + game.move(game.gameView.gameBoardView.blocks[0][0]); + game.move(game.gameView.gameBoardView.blocks[0][1]); + game.move(game.gameView.gameBoardView.blocks[1][0]); + game.move(game.gameView.gameBoardView.blocks[0][2]); + game.move(game.gameView.gameBoardView.blocks[2][0]); + + assertEquals("Player 1 wins!", game.gameModel.getFinalResult()); + // assertEquals(Player.PLAYER_2, game.gameModel.getPlayer()); + // The game should be over + assertEquals(false, game.gameModel.blocksData[0][2].getIsLegalMove()); + } + + @Test + public void testTieGame() { + // Make a series of moves that results in a tie game + game.move(game.gameView.gameBoardView.blocks[0][0]); // Player 1 + game.move(game.gameView.gameBoardView.blocks[0][1]); // Player 2 + game.move(game.gameView.gameBoardView.blocks[0][2]); // Player 1 + game.move(game.gameView.gameBoardView.blocks[2][2]); // Player 2 + game.move(game.gameView.gameBoardView.blocks[2][1]); // Player 1 + game.move(game.gameView.gameBoardView.blocks[2][0]); // Player 2 + game.move(game.gameView.gameBoardView.blocks[1][0]); // Player 1 + game.move(game.gameView.gameBoardView.blocks[1][1]); // Player 2 + game.move(game.gameView.gameBoardView.blocks[1][2]); // Player 1 + // System.out.printf("%s", game.gameModel.getFinalResult()); + + assertEquals("Game ends in a draw", game.gameModel.getFinalResult()); + } + + @Test + public void testResetGame() { + // Reset the game and check if the initial configuration is as expected + game.resetGame(); + assertEquals(Player.PLAYER_1, game.gameModel.getPlayer()); + assertEquals(9, game.gameModel.movesLeft); + // The game should not be over + assertEquals(true, game.gameModel.blocksData[0][2].getIsLegalMove()); + assertNull(game.gameModel.getFinalResult()); + } + + @Test + public void testUndoNotAllowedBeforeMove() { + // Undo should not be allowed if no moves have been made + game.undoMove(); + } + + @Test + public void testUndoMove() { + + // Make a move + game.move(game.gameView.gameBoardView.blocks[0][0]); + + // Verify the move was made successfully + assertEquals(Player.PLAYER_2, game.gameModel.getPlayer()); + assertEquals(8, game.gameModel.movesLeft); + + // Undo the move + game.undoMove(); + + // Verify the game is updated appropriately + assertEquals(Player.PLAYER_1, game.gameModel.getPlayer()); + assertEquals(9, game.gameModel.movesLeft); + } + }