Intial commit

This commit is contained in:
Mario Fetka
2024-05-27 16:13:40 +02:00
parent f8dc12b10a
commit d71d446104
2495 changed files with 539746 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
Tcl-DP: Tic Tac Toe
This creates a simple distributed Tic Tac Toe game, displayed using
Tk widgets. It is an example of using a Tcl-DP distributed object.
playerX.tcl -- script for player X, must be run first
playerO.tcl -- script for player O, must be run after playerX.tcl
The following two files are shared by player X and player O.
board.tcl -- definition of the distributed board class
interface.tcl -- definition of user interface of Tk widgets
--------------------------------------------------------------------
First, start player X...
Run wish.
Type "source playerX.tcl" and answer the questions;
--------------------------------------------------------------------
Second, start player O...
Run wish, as another process.
Type "source playerO.tcl" and answer the questions;
--------------------------------------------------------------------
Player X is the RPC server. Player O is the RPC client. (Hence,
player X must be set up before player O.) Player X creates a Tic
Tac Toe board object, which gets distributed to player O. Each
player process locally updates its Tk interface, as the Tk
widgets of the interface are not distributed objects.
Because the board is a distributed object, callbacks from user
actions are very simple. Any changes to slots of the board
object in a callback are automatically propagated to all
processes.

View File

@@ -0,0 +1,107 @@
#
# board.tcl -- Tcl/Tk script that defines a Tic Tac Toe board object.
#
# The board object is defined using Tcl scripting only.
# Normally, objects are created in C (as structs), such as
# with Tk widgets, and have a Tcl access interface.
#
# The board has one slot, state, which is a list of nine entries.
# Each entry may be X, O, or S (space).
#
# board -- creator procedure, works like a Tk widget creator.
#
# usage : board name ?configure-options ...?
#
package require dp 4.0
proc board {aBoard args} {
# Create a procedure to represent a new board object.
# This new board object (procedure) will have the name of $aBoard;
#
dp_objectCreateProc board $aBoard;
# Give the new board object one slot, called state;
#
dp_objectSlotSet $aBoard state {S S S S S S S S S};
# Finish configuration of the new board object;
#
eval $aBoard configure $args;
return $aBoard;
}
#
# Method definitions for objects of class Tic Tac Toe board;
#
# Distributed objects must have the methods of configure and slot-value,
# according to Tcl-DP distributed object protocol;
#
# configure - configure the slots of board object;
# slot-value - return value of one slot of board object;
#
# The methods configure and slot-value that are defined here
# use the object utility procedures that come
# with the Tcl-DP package;
#
proc board.configure {aBoard args} {
return [eval dp_objectConfigure board $aBoard $args];
}
proc board.slot-value {aBoard slot} {
return [dp_objectSlot $aBoard $slot];
}
# In the following board methods, note the use of dp_setf and dp_getf
# instead of objectSlotSet and objectSlot; dp_setf and dp_getf
# are used for slot access to Tcl-DP distributed objects;
#
# clear - clear entries of board;
#
proc board.clear {aBoard} {
dp_setf $aBoard state {S S S S S S S S S};
return $aBoard;
}
# entryGet - get entry at position x,y (0-2, 0-2);
# entrySet - set entry at position x,y (0-2, 0-2);
#
proc board.entryGet {aBoard x y} {
set state [dp_getf $aBoard state];
set position [expr ($x*3)+$y];
return [lindex $state $position];
}
proc board.entrySet {aBoard x y value} {
set state [dp_getf $aBoard state];
set position [expr ($x*3)+$y];
dp_setf $aBoard state [lreplace $state $position $position $value];
return $value;
}
# print - pretty print board to stdout;
#
proc board.print {aBoard} {
for {set row 0} {$row <= 2} {incr row} {
for {set col 0} {$col <= 2} {incr col} {
set entry [$aBoard entryGet $col $row];
case $entry in {
{S} {set symbol " "}
{default} {set symbol $entry}
}
puts stdout $symbol nonewline;
}
puts stdout "";
}
}

View File

@@ -0,0 +1,88 @@
# interface.tcl -- Tcl/Tk script that defines the GUI interface
# of the Tic Tac Toe game; Since both player X and player O
# share the same interface, they both use this script.
#
# The global variable player must be set up beforehand;
#
wm title . "TTT - $player";
# The following procedure is the callback for when a user
# presses a Tic Tac Toe GUI button;
#
proc mark {col row} {
global player;
# Get the current entry of the board of the given column and row.
#
set entry [.board entryGet $col $row];
if {[string compare S $entry] == 0} {
# Set the entry of the board to the player's symbol,
# if the current entry is an S (space).
#
.board entrySet $col $row $player;
# Since the board is a distributed object, any slot changes to
# it will get automatically distributed the other player.
#
} else {
# Otherwise, complain to the user;
#
puts stdout "";
puts stdout "Cannot mark that entry ($col,$row).";
puts stdout "Already marked with an $entry.";
}
}
# Procedure to create a column of Tic Tac Toe GUI buttons;
#
proc column {w i} {
pack append $w \
[frame $w.c$i] {left fillx filly};
pack append $w.c$i \
[button $w.c$i.0 -command "mark $i 0" -width 2] {top fillx} \
[button $w.c$i.1 -command "mark $i 1" -width 2] {top fillx} \
[button $w.c$i.2 -command "mark $i 2" -width 2] {top fillx};
}
# Procedure to update the text of those Tic Tac Toe GUI buttons
# according to the state of the distributed board object;
#
proc DisplayUpdate {} {
for {set row 0} {$row <= 2} {incr row} {
for {set col 0} {$col <= 2} {incr col} {
set entry [.board entryGet $col $row];
case $entry in {
{S} {set symbol " "}
{default} {set symbol $entry}
}
.main.c$col.$row configure -text $symbol;
}
}
}
# Instantiate the interface;
#
pack append . [frame .main] top;
column .main 0;
column .main 1;
column .main 2;
pack append .main \
[button .main.clear -text "Clear" -command ".board clear"] \
{top fillx} \
[button .main.quit -text "Quit" -command "exit"] \
{top fillx};

View File

@@ -0,0 +1,47 @@
#
# playerO.tcl -- Tcl/Tk script for player O, the RPC client.
#
# This script should be run after running the player X script.
#
package require dp 4.0
set player O;
puts stdout "Tic Tac Toe - player O";
# Get information from user;
#
puts stdout "Enter the host address of player X: " nonewline;
gets stdin host;
puts stdout "Enter the port number of player X: " nonewline;
gets stdin port;
# Connect to server (player X) as an RPC client;
#
set server [dp_MakeRPCClient $host $port];
# Instead of creating a local board object, we ask the server to
# distribute its board object to us;
#
source board.tcl;
set remFile [dp_RPC $server set dp_rpcFile]
dp_RPC $server eval dp_DistributeObject .board $remFile board;
# Initialize the user interface;
#
source interface.tcl;
# Trigger a user interface update whenever the state slot of
# the distributed board object changes;
#
dp_SetTrigger after .board state DisplayUpdate

View File

@@ -0,0 +1,43 @@
#
# playerX.tcl -- Tcl/Tk script for player X, the RPC server.
#
# This script should be run before running the player O script.
#
package require dp 4.0
set player X;
puts stdout "Tic Tac Toe - player X";
# Get information from user;
#
puts stdout "Enter an unused port number (ex: 8765) : " nonewline;
gets stdin port;
# Make an RPC server socket, which will be waiting for player O
# to connect through the supplied port number;
#
dp_MakeRPCServer $port
# Create a local board object that will get distributed to player O;
#
source board.tcl;
board .board;
# Initialize the user interface;
#
source interface.tcl;
# Trigger a user interface update whenever the state slot of
# the distributed board object changes;
#
dp_SetTrigger after .board state DisplayUpdate