Removed spaces from top-level directory names.

Spaces tend to cause annoyances in a Unix-style shell environment.
This change fixes that.
This commit is contained in:
Chris Reuter
2021-11-21 18:30:21 -05:00
parent df2e7426eb
commit d26dbf036a
1725 changed files with 0 additions and 0 deletions

7
04_Awari/README.md Normal file
View File

@@ -0,0 +1,7 @@
### Awari
As published in Basic Computer Games (1978)
https://www.atariarchives.org/basicgames/showpage.php?page=6
Downloaded from Vintage Basic at
http://www.vintage-basic.net/games.html

70
04_Awari/awari.bas Normal file
View File

@@ -0,0 +1,70 @@
5 PRINT TAB(34);"AWARI"
7 PRINT TAB(15);"CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
10 DATA 0
15 DIM B(13),G(13),F(50):READ N
20 PRINT:PRINT:E=0
25 FOR I=0 TO 12:B(I)=3:NEXT I
30 C=0:F(N)=0:B(13)=0:B(6)=0
35 GOSUB 500
40 PRINT "YOUR MOVE";:GOSUB 110
45 IF E=0 THEN 80
50 IF M=H THEN GOSUB 100
55 IF E=0 THEN 80
60 PRINT "MY MOVE IS ";:GOSUB 800
65 IF E=0 THEN 80
70 IF M=H THEN PRINT ",";:GOSUB 800
75 IF E>0 THEN 35
80 PRINT:PRINT"GAME OVER"
85 D=B(6)-B(13):IF D<0 THEN PRINT "I WIN BY";-D;"POINTS":GOTO 20
90 N=N+1:IF D=0 THEN PRINT "DRAWN GAME":GOTO 20
95 PRINT "YOU WIN BY";D;"POINTS":GOTO 20
100 PRINT "AGAIN";
110 INPUT M:IF M<7 THEN IF M>0 THEN M=M-1:GOTO 130
120 PRINT "ILLEGAL MOVE":GOTO 100
130 IF B(M)=0 THEN 120
140 H=6:GOSUB 200
150 GOTO 500
200 K=M:GOSUB 600
205 E=0:IF K>6 THEN K=K-7
210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K
215 FOR I=0 TO 5:IF B(I)<>0 THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN
235 GOTO 220
500 PRINT:PRINT" ";
505 FOR I=12 TO 7 STEP -1:GOSUB 580
510 NEXT I
515 PRINT:I=13:GOSUB 580
520 PRINT " ";:PRINT B(6):PRINT " ";
525 FOR I=0 TO 5:GOSUB 580
530 NEXT I
535 PRINT:PRINT:RETURN
580 IF B(I)<10 THEN PRINT " ";
585 PRINT B(I);:RETURN
600 P=B(M):B(M)=0
605 FOR P=P TO 1 STEP -1:M=M+1:IF M>13 THEN M=M-14
610 B(M)=B(M)+1:NEXT P
615 IF B(M)=1 THEN IF M<>6 THEN IF M<>13 THEN IF B(12-M)<>0 THEN 625
620 RETURN
625 B(H)=B(H)+B(12-M)+1:B(M)=0:B(12-M)=0:RETURN
800 D=-99:H=13
805 FOR I=0 TO 13:G(I)=B(I):NEXT I
810 FOR J=7 TO 12:IF B(J)=0 THEN 885
815 Q=0:M=J:GOSUB 600
820 FOR I=0 TO 5:IF B(I)=0 THEN 845
825 L=B(I)+I:R=0
830 IF L>13 THEN L=L-14:R=1:GOTO 830
835 IF B(L)=0 THEN IF L<>6 THEN IF L<>13 THEN R=B(12-L)+R
840 IF R>Q THEN Q=R
845 NEXT I
850 Q=B(13)-B(6)-Q:IF C>8 THEN 875
855 K=J:IF K>6 THEN K=K-7
860 FOR I=0 TO N-1:IF F(N)*6+K=INT(F(I)/6^(7-C)+.1) THEN Q=Q-2
870 NEXT I
875 FOR I=0 TO 13:B(I)=G(I):NEXT I
880 IF Q>=D THEN A=J:D=Q
885 NEXT J
890 M=A:PRINT CHR$(42+M);:GOTO 200
900 FOR I=0 TO N-1:PRINT B(I):NEXT I
999 END

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/)

206
04_Awari/java/Awari.java Normal file
View File

@@ -0,0 +1,206 @@
import java.util.Scanner;
import java.util.Random;
public class Awari{
int []board;
private final int playerPits;
private final int computerPits;
private final int playerHome;
private final int computerHome;
Scanner input;
int sumPlayer;
int sumComputer;
Awari(){
input = new Scanner(System.in);
playerPits = 0;
computerPits = 7;
playerHome = 6;
computerHome = 13;
sumPlayer = 18;
sumComputer = 18;
board = new int [14];
for (int i=0;i<6;i++){
board[playerPits+i]=3;
board[computerPits+i]=3;
}
System.out.println(" AWARI");
System.out.println("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
printBoard();
playerMove(true);
}
private void printBoard(){
System.out.print("\n ");
for (int i=0;i<6;i++){
System.out.print(String.format("%2d",board[12-i]));
System.out.print(" ");
}
System.out.println("");
System.out.print(String.format("%2d",board[computerHome]));
System.out.print(" ");
System.out.println(String.format("%2d",board[playerHome]));
System.out.print(" ");
for(int i=0;i<6;i++){
System.out.print(String.format("%2d",board[playerPits+i]));
System.out.print(" ");
}
System.out.println("");
}
private void playerMove(boolean val){
System.out.println("\nComputerSum PlayerSum"+sumComputer+" "+sumPlayer);
if(val == true)
System.out.print("YOUR MOVE? ");
else
System.out.print("AGAIN? ");
int move = input.nextInt();
while(move<1||move>6||board[move-1]==0){
System.out.print("INVALID MOVE!!! TRY AGAIN ");
move = input.nextInt();
}
int seeds = board[move-1];
board[move-1] = 0;
sumPlayer -= seeds;
int last_pos = distribute(seeds,move);
if(last_pos == playerHome){
printBoard();
if(isGameOver(true)){
System.exit(0);
}
playerMove(false);
}
else if(board[last_pos] == 1&&last_pos != computerHome){
int opp = calculateOpposite(last_pos);
if(last_pos<6){
sumPlayer+=board[opp];
sumComputer-=board[opp];
}
else{
sumComputer+=board[opp];
sumPlayer-=board[opp];
}
board[last_pos]+=board[opp];
board[opp] = 0;
printBoard();
if(isGameOver(false)){
System.exit(0);
}
computerMove(true);
}
else{
printBoard();
if(isGameOver(false)){
System.exit(0);
}
computerMove(true);
}
}
private void computerMove(boolean value){
int val=-1;
System.out.println("\nComputerSum PlayerSum"+sumComputer+" "+sumPlayer);
for(int i=0;i<6;i++){
if(6-i == board[computerPits+i])
val = i;
}
int move ;
if(val == -1)
{
Random random = new Random();
move = random.nextInt(6)+computerPits;
while(board[move] == 0){
move = random.nextInt(6)+computerPits;
}
if(value == true)
System.out.println(String.format("MY MOVE IS %d ",move-computerPits+1));
else
System.out.println(String.format(",%d",move-computerPits+1));
int seeds = board[move];
board[move] = 0;
sumComputer-=seeds;
int last_pos = distribute(seeds,move+1);
if(board[last_pos] == 1&&last_pos != playerHome){
int opp = calculateOpposite(last_pos);
if(last_pos<6){
sumPlayer+=board[opp];
sumComputer-=board[opp];
}
else{
sumComputer+=board[opp];
sumPlayer-=board[opp];
}
board[last_pos]+=board[opp];
board[opp] = 0;
printBoard();
if(isGameOver(false)){
System.exit(0);
}
}
else{
printBoard();
if(isGameOver(false)){
System.exit(0);
}
}
playerMove(true);
}
else {
move = val+computerPits;
if(value == true)
System.out.print(String.format("MY MOVE IS %d",move-computerPits+1));
else
System.out.print(String.format(",%d",move-computerPits+1));
int seeds = board[move];
board[move] = 0;
sumComputer-=seeds;
int last_pos = distribute(seeds,move+1);
if(last_pos == computerHome){
if(isGameOver(true) ){
System.exit(0);
}
computerMove(false);
}
}
}
private int distribute(int seeds, int pos){
while(seeds!=0){
if(pos==14)
pos=0;
if(pos<6)
sumPlayer++;
else if(pos>6&&pos<13)
sumComputer++;
board[pos]++;
pos++;
seeds--;
}
return pos-1;
}
private int calculateOpposite(int pos){
return 12-pos;
}
private boolean isGameOver(boolean show){
if(sumPlayer == 0 || sumComputer == 0){
if(show)
printBoard();
System.out.println("GAME OVER");
if(board[playerHome]>board[computerHome]){
System.out.println(String.format("YOU WIN BY %d POINTS",board[playerHome]-board[computerHome]));
}
else if(board[playerHome]<board[computerHome]){
System.out.println(String.format("YOU LOSE BY %d POINTS",board[computerHome]-board[playerHome]));
}
else{
System.out.println("DRAW");
}
return true;
}
return false;
}
}

View File

@@ -0,0 +1,5 @@
public class AwariGame {
public static void main(String[] args) {
Awari awari = new Awari();
}
}

3
04_Awari/java/README.md Normal file
View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Oracle Java](https://openjdk.java.net/)

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Shells)

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>AWARI</title>
</head>
<body>
<pre id="output" style="font-size: 12pt;"></pre>
<script src="awari.js"></script>
</body>
</html>

View File

@@ -0,0 +1,259 @@
// AWARI
//
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
//
function print(str)
{
document.getElementById("output").appendChild(document.createTextNode(str));
}
function input()
{
var input_element;
var input_str;
return new Promise(function (resolve) {
input_element = document.createElement("INPUT");
print("? ");
input_element.setAttribute("type", "text");
input_element.setAttribute("length", "50");
document.getElementById("output").appendChild(input_element);
input_element.focus();
input_str = undefined;
input_element.addEventListener("keydown", function (event) {
if (event.keyCode == 13) {
input_str = input_element.value;
document.getElementById("output").removeChild(input_element);
print(input_str);
print("\n");
resolve(input_str);
}
});
});
}
function tab(space)
{
var str = "";
while (space-- > 0)
str += " ";
return str;
}
print(tab(34) + "AWARI\n");
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
n = 0;
b = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];
g = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];
f = [];
for (i = 0; i <= 50; i++) {
f[i] = 0;
}
function show_number(number)
{
if (number < 10)
print(" " + number + " ");
else
print(" " + number + " ");
}
function show_board()
{
var i;
print("\n");
print(" ");
for (i = 12; i >= 7; i--)
show_number(b[i]);
print("\n");
i = 13;
show_number(b[i]);
print(" " + b[6] + "\n");
print(" ");
for (i = 0; i <= 5; i++)
show_number(b[i]);
print("\n");
print("\n");
}
function do_move()
{
k = m;
adjust_board();
e = 0;
if (k > 6)
k -= 7;
c++;
if (c < 9)
f[n] = f[n] * 6 + k
for (i = 0; i <= 5; i++) {
if (b[i] != 0) {
for (i = 7; i <= 12; i++) {
if (b[i] != 0) {
e = 1;
return;
}
}
}
}
}
function adjust_board()
{
p = b[m];
b[m] = 0;
while (p >= 1) {
m++;
if (m > 13)
m -= 14;
b[m]++;
p--;
}
if (b[m] == 1) {
if (m != 6 && m != 13) {
if (b[12 - m] != 0) {
b[h] += b[12 - m] + 1;
b[m] = 0;
b[12 - m] = 0;
}
}
}
}
function computer_move()
{
d = -99;
h = 13;
for (i = 0; i<= 13; i++) // Backup board
g[i] = b[i];
for (j = 7; j <= 12; j++) {
if (b[j] == 0)
continue;
q = 0;
m = j;
adjust_board();
for (i = 0; i <= 5; i++) {
if (b[i] == 0)
continue;
l = b[i] + i;
r = 0;
while (l > 13) {
l -= 14;
r = 1;
}
if (b[l] == 0) {
if (l != 6 && l != 13)
r = b[12 - l] + r;
}
if (r > q)
q = r;
}
q = b[13] - b[6] - q;
if (c < 8) {
k = j;
if (k > 6)
k -= 7;
for (i = 0; i <= n - 1; i++) {
if (f[n] * 6 + k == Math.floor(f[i] / Math.pow(7 - c, 6) + 0.1))
q -= 2;
}
}
for (i = 0; i <= 13; i++) // Restore board
b[i] = g[i];
if (q >= d) {
a = j;
d = q;
}
}
m = a;
print(m - 6);
do_move();
}
// Main program
async function main()
{
while (1) {
print("\n");
print("\n");
e = 0;
for (i = 0; i <= 12; i++)
b[i] = 3;
c = 0;
f[n] = 0;
b[13] = 0;
b[6] = 0;
while (1) {
show_board();
print("YOUR MOVE");
while (1) {
m = parseInt(await input());
if (m < 7) {
if (m > 0) {
m--;
if (b[m] != 0)
break;
}
}
print("ILLEGAL MOVE\n");
print("AGAIN");
}
h = 6;
do_move();
show_board();
if (e == 0)
break;
if (m == h) {
print("AGAIN");
while (1) {
m = parseInt(await input());
if (m < 7) {
if (m > 0) {
m--;
if (b[m] != 0)
break;
}
}
print("ILLEGAL MOVE\n");
print("AGAIN");
}
h = 6;
do_move();
show_board();
}
if (e == 0)
break;
print("MY MOVE IS ");
computer_move();
if (e == 0)
break;
if (m == h) {
print(",");
computer_move();
}
if (e == 0)
break;
}
print("\n");
print("GAME OVER\n");
d = b[6] - b[13];
if (d < 0)
print("I WIN BY " + -d + " POINTS\n");
else if (d == 0) {
n++;
print("DRAWN GAME\n");
} else {
n++;
print("YOU WIN BY " + d + " POINTS\n");
}
}
}
main();

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))

3
04_Awari/perl/README.md Normal file
View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Perl](https://www.perl.org/)

View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Python](https://www.python.org/about/)

402
04_Awari/python/awari.py Normal file
View File

@@ -0,0 +1,402 @@
"""
AWARI
An ancient African game (see also Kalah, Mancala).
Ported by Dave LeCompte
"""
"""
PORTING NOTES
This game started out as 70 lines of BASIC, and I have ported it
before. I find it somewhat amazing how efficient (densely packed) the
original code is. Of course, the original code has fairly cryptic
variable names (as was forced by BASIC's limitation on long (2+
character) variable names). I have done my best here to interpret what
each variable is doing in context, and rename them appropriately.
I have endeavored to leave the logic of the code in place, as it's
interesting to see a 2-ply game tree evaluation written in BASIC,
along with what a reader in 2021 would call "machine learning".
As each game is played, the move history is stored as base-6
digits stored losing_book[game_number]. If the human player wins or
draws, the computer increments game_number, effectively "recording"
that loss to be referred to later. As the computer evaluates moves, it
checks the potential game state against these losing game records, and
if the potential move matches with the losing game (up to the current
number of moves), that move is evaluated at a two point penalty.
Compare this, for example with MENACE, a mechanical device for
"learning" tic-tac-toe:
https://en.wikipedia.org/wiki/Matchbox_Educable_Noughts_and_Crosses_Engine
The base-6 representation allows game history to be VERY efficiently
represented. I considered whether to rewrite this representation to be
easier to read, but I elected to TRY to document it, instead.
Another place where I have made a difficult decision between accuracy
and correctness is inside the "wrapping" code where it considers
"while human_move_end > 13". The original BASIC code reads:
830 IF L>13 THEN L=L-14:R=1:GOTO 830
I suspect that the intention is not to assign 1 to R, but to increment
R. I discuss this more in a porting note comment next to the
translated code. If you wish to play a more accurate version of the
game as written in the book, you can convert the increment back to an
assignment.
I continue to be impressed with this jewel of a game; as soon as I had
the AI playing against me, it was beating me. I've been able to score
a few wins against the computer, but even at its 2-ply lookahead, it
beats me nearly always. I would like to become better at this game to
explore the effectiveness of the "losing book" machine learning.
EXERCISES FOR THE READER
One could go many directions with this game:
- change the initial number of stones in each pit
- change the number of pits
- only allow capturing if you end on your side of the board
- don't allow capturing at all
- don't drop a stone into the enemy "home"
- go clockwise, instead
- allow the player to choose to go clockwise or counterclockwise
- instead of a maximum of two moves, allow each move that ends on the
"home" to be followed by a free move.
- increase the AI lookahead
- make the scoring heuristic a little more nuanced
- store history to a file on disk (or in the cloud!) to allow the AI
to learn over more than a single session
"""
game_number = 0
move_count = 0
losing_book = []
n = 0
MAX_HISTORY = 9
LOSING_BOOK_SIZE = 50
def print_with_tab(space_count, msg):
if space_count > 0:
spaces = " " * space_count
else:
spaces = ""
print(spaces + msg)
def draw_pit(line, board, pit_index):
val = board[pit_index]
line = line + " "
if val < 10:
line = line + " "
line = line + str(val) + " "
return line
def draw_board(board):
print()
# Draw the top (computer) pits
line = " "
for i in range(12, 6, -1):
line = draw_pit(line, board, i)
print(line)
# Draw the side (home) pits
line = draw_pit("", board, 13)
line += " " * 24
line = draw_pit(line, board, 6)
print(line)
# Draw the bottom (player) pits
line = " "
for i in range(0, 6):
line = draw_pit(line, board, i)
print(line)
print()
print()
def play_game(board):
# Place the beginning stones
for i in range(0, 13):
board[i] = 3
# Empty the home pits
board[6] = 0
board[13] = 0
global move_count
move_count = 0
# clear the history record for this game
losing_book[game_number] = 0
while True:
draw_board(board)
print("YOUR MOVE")
landing_spot, is_still_going, home = player_move(board)
if not is_still_going:
break
if landing_spot == home:
landing_spot, is_still_going, home = player_move_again(board)
if not is_still_going:
break
print("MY MOVE")
landing_spot, is_still_going, home, msg = computer_move("", board)
if not is_still_going:
print(msg)
break
if landing_spot == home:
landing_spot, is_still_going, home, msg = computer_move(msg + " , ", board)
if not is_still_going:
print(msg)
break
print(msg)
game_over(board)
def computer_move(msg, board):
# This function does a two-ply lookahead evaluation; one computer
# move plus one human move.
#
# To do this, it makes a copy (temp_board) of the board, plays
# each possible computer move and then uses math to work out what
# the scoring heuristic is for each possible human move.
#
# Additionally, if it detects that a potential move puts it on a
# series of moves that it has recorded in its "losing book", it
# penalizes that move by two stones.
best_quality = -99
# Make a copy of the board, so that we can experiment. We'll put
# everything back, later.
temp_board = board[:]
# For each legal computer move 7-12
for computer_move in range(7, 13):
if board[computer_move] == 0:
continue
do_move(computer_move, 13, board) # try the move (1 move lookahead)
best_player_move_quality = 0
# for all legal human moves 0-5 (responses to computer move computer_move)
for human_move_start in range(0, 6):
if board[human_move_start] == 0:
continue
human_move_end = board[human_move_start] + human_move_start
this_player_move_quality = 0
# If this move goes around the board, wrap backwards.
#
# PORTING NOTE: The careful reader will note that I am
# incrementing this_player_move_quality for each wrap,
# while the original code only set it equal to 1.
#
# I expect this was a typo or oversight, but I also
# recognize that you'd have to go around the board more
# than once for this to be a difference, and even so, it
# would be a very small difference; there are only 36
# stones in the game, and going around the board twice
# requires 24 stones.
while human_move_end > 13:
human_move_end = human_move_end - 14
this_player_move_quality += 1
if (
(board[human_move_end] == 0)
and (human_move_end != 6)
and (human_move_end != 13)
):
# score the capture
this_player_move_quality += board[12 - human_move_end]
if this_player_move_quality > best_player_move_quality:
best_player_move_quality = this_player_move_quality
# This is a zero sum game, so the better the human player's
# move is, the worse it is for the computer player.
computer_move_quality = board[13] - board[6] - best_player_move_quality
if move_count < MAX_HISTORY:
move_digit = computer_move
if move_digit > 6:
move_digit = move_digit - 7
# Calculate the base-6 history representation of the game
# with this move. If that history is in our "losing book",
# penalize that move.
for prev_game_number in range(game_number):
if losing_book[game_number] * 6 + move_digit == int(
losing_book[prev_game_number] / 6 ^ (7 - move_count) + 0.1
):
computer_move_quality -= 2
# Copy back from temporary board
for i in range(14):
board[i] = temp_board[i]
if computer_move_quality >= best_quality:
best_move = computer_move
best_quality = computer_move_quality
selected_move = best_move
move_str = chr(42 + selected_move)
if msg:
msg += ", " + move_str
else:
msg = move_str
move_number, is_still_going, home = execute_move(selected_move, 13, board)
return move_number, is_still_going, home, msg
def game_over(board):
print()
print("GAME OVER")
pit_difference = board[6] - board[13]
if pit_difference < 0:
print(f"I WIN BY {-pit_difference} POINTS")
else:
global n
n = n + 1
if pit_difference == 0:
print("DRAWN GAME")
else:
print(f"YOU WIN BY {pit_difference} POINTS")
def do_capture(m, home, board):
board[home] += board[12 - m] + 1
board[m] = 0
board[12 - m] = 0
def do_move(m, home, board):
move_stones = board[m]
board[m] = 0
for stones in range(move_stones, 0, -1):
m = m + 1
if m > 13:
m = m - 14
board[m] += 1
if board[m] == 1:
# capture
if (m != 6) and (m != 13) and (board[12 - m] != 0):
do_capture(m, home, board)
return m
def player_has_stones(board):
for i in range(6):
if board[i] > 0:
return True
return False
def computer_has_stones(board):
for i in range(7, 13):
if board[i] > 0:
return True
return False
def execute_move(move, home, board):
move_digit = move
last_location = do_move(move, home, board)
if move_digit > 6:
move_digit = move_digit - 7
global move_count
move_count += 1
if move_count < MAX_HISTORY:
# The computer keeps a chain of moves in losing_book by
# storing a sequence of moves as digits in a base-6 number.
#
# game_number represents the current game,
# losing_book[game_number] records the history of the ongoing
# game. When the computer evaluates moves, it tries to avoid
# moves that will lead it into paths that have led to previous
# losses.
losing_book[game_number] = losing_book[game_number] * 6 + move_digit
if player_has_stones(board) and computer_has_stones(board):
is_still_going = True
else:
is_still_going = False
return last_location, is_still_going, home
def player_move_again(board):
print("AGAIN")
return player_move(board)
def player_move(board):
while True:
print("SELECT MOVE 1-6")
m = int(input()) - 1
if m > 5 or m < 0 or board[m] == 0:
print("ILLEGAL MOVE")
continue
break
ending_spot, is_still_going, home = execute_move(m, 6, board)
draw_board(board)
return ending_spot, is_still_going, home
def main():
print_with_tab(34, "AWARI")
print_with_tab(15, "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
board = [0] * 14 # clear the board representation
global losing_book
losing_book = [0] * LOSING_BOOK_SIZE # clear the "machine learning" state
while True:
play_game(board)
if __name__ == "__main__":
main()

3
04_Awari/ruby/README.md Normal file
View File

@@ -0,0 +1,3 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Ruby](https://www.ruby-lang.org/en/)

3
04_Awari/vbnet/README.md Normal file
View File

@@ -0,0 +1,3 @@
Original BASIC source [downloaded from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Visual Basic .NET](https://en.wikipedia.org/wiki/Visual_Basic_.NET)