Skip to content

Commit a581189

Browse files
authored
Lesson 4 committed
1 parent e1055ce commit a581189

40 files changed

+242531
-0
lines changed
+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env bash
2+
3+
# A blank line is a line containing (only) 0 or more whitespaces
4+
regex_blank="^[[:space:]]*$"
5+
6+
function read_chunk()
7+
{
8+
while read -r line
9+
do
10+
# If the first argument is 1, print this line
11+
[[ $1 -eq 1 ]] && echo "$line"
12+
13+
# Quit if line is blank
14+
[[ $line =~ $regex_blank ]] && return 0
15+
done
16+
17+
# Quit with failure return code here since read could not get another line
18+
return 1
19+
}
20+
21+
22+
function show_nth_game()
23+
{
24+
local count=1
25+
local should_print=0
26+
27+
# As long as count is less than or equal to N
28+
while [[ $count -le $1 ]]
29+
do
30+
# Have we reached the Nth game, if so should_print is set
31+
[[ $count -eq $1 ]] && should_print=1
32+
33+
# Process the first set of lines in a game, and printing only if should_print is 1
34+
# Exit if the read_chunk returned non-zero
35+
read_chunk $should_print || return
36+
37+
# Repeat for the second chunk
38+
read_chunk $should_print
39+
40+
# Increment the count and repeat the whole process
41+
count=$(( count + 1 ))
42+
43+
# Quit after printing the game
44+
[[ $should_print -eq 1 ]] && break
45+
done
46+
}
47+
48+
49+
# reads through the initial game data of PGN data
50+
# and sets the variable found to 1 if the specified regex matched any line
51+
# Returns nonzero exit code if end of stream was encountered
52+
function filter_game()
53+
{
54+
# Initially assume not found
55+
found=0
56+
57+
while read -r line
58+
do
59+
# Set found to 1 if the line matches the filter
60+
[[ $line =~ $1 ]] && found=1
61+
62+
# If line is blank, we have reached end of game attributes, but not eos, so return 0
63+
[[ $line =~ $regex_blank ]] && return 0
64+
done
65+
66+
# If it gets here there is no more data, so return nonzero
67+
return 1
68+
}
69+
70+
71+
# Read all the lines of the PGN move list and concatenate them into the variable moves
72+
function read_moves()
73+
{
74+
# Clear the moves variable
75+
moves=''
76+
77+
while read -r line
78+
do
79+
# Quit if line is blank
80+
[[ $line =~ $regex_blank ]] && return 0
81+
82+
# Append the line to moves with space in between
83+
moves="${moves} ${line}"
84+
85+
done
86+
87+
# Quit with failure return code here since read could not get another line
88+
return 1
89+
}
90+
91+
92+
# counts the number of moves in the moves list of a PGN format game
93+
# Assumes that "moves" is a string containing the complete moves list
94+
# result is stored in num_moves
95+
function count_moves()
96+
{
97+
# split moves into an array with the '.' as delimiter
98+
IFS='.'
99+
local moves_arr=( $moves )
100+
101+
# The second last entry contains the last moves index
102+
# Use the negative array index feature of bash to get it
103+
local second_last=${moves_arr[@]: -2 : 1}
104+
105+
# Now Second last contains something like "Kg1 Qg3+ 31" and the last word is the count
106+
IFS=' '
107+
local second_last_arr=( $second_last )
108+
109+
# Again use negative array index to get the number into moves_count
110+
num_moves=${second_last_arr[@]: -1 : 1}
111+
}
112+
113+
114+
# Display the indexes of all games that have a win in fewer than the specified moves
115+
function show_games_won_in()
116+
{
117+
local index=1
118+
119+
# While we have not reached the end of stream
120+
while filter_game '\[Result "(1-0|0-1)"\]'
121+
do
122+
# Check if this game has a result
123+
if [[ $found -eq 1 ]]
124+
then
125+
126+
# Read and count the moves
127+
read_moves
128+
count_moves
129+
130+
# Display the game index and moves if it has fewer than $1 moves
131+
[[ $num_moves -le $1 ]] && echo "Game $index: $num_moves moves" && echo "$moves" && echo
132+
133+
else # No result, skip over the moves list
134+
135+
read_chunk 0
136+
fi
137+
138+
# Increment the index
139+
index=$(( index + 1 ))
140+
done
141+
}
142+
143+
144+
getopts 'm:n:' opt
145+
146+
case $opt in
147+
m)
148+
echo Displaying games won in "$OPTARG" moves or less
149+
echo
150+
show_games_won_in "$OPTARG"
151+
;;
152+
153+
n)
154+
echo Displaying Game "#$OPTARG"
155+
echo
156+
show_nth_game "$OPTARG"
157+
;;
158+
esac
159+
160+
161+
162+
163+
164+
165+
+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#!/usr/bin/env bash
2+
3+
4+
function read_chunk()
5+
{
6+
while read -r line
7+
do
8+
# If the first argument is 1, print this line
9+
[[ $1 -eq 1 ]] && echo "$line"
10+
11+
# Quit if line is blank
12+
[[ -z $line ]] && return 0
13+
done
14+
15+
# Quit with failure return code here since read could not get another line
16+
return 1
17+
}
18+
19+
20+
function show_nth_game()
21+
{
22+
local count=1
23+
local should_print=0
24+
25+
# As long as count is less than or equal to N
26+
while [[ $count -le $1 ]]
27+
do
28+
# Have we reached the Nth game, if so should_print is set
29+
[[ $count -eq $1 ]] && should_print=1
30+
31+
# Process the first set of lines in a game, and printing only if should_print is 1
32+
# Exit if the read_chunk returned non-zero
33+
read_chunk $should_print || return
34+
35+
# Repeat for the second chunk
36+
read_chunk $should_print
37+
38+
# Increment the count and repeat the whole process
39+
count=$(( count + 1 ))
40+
41+
# Quit after printing the game
42+
[[ $should_print -eq 1 ]] && break
43+
done
44+
}
45+
46+
47+
# reads through the initial game data of PGN data
48+
# and sets the variable found to 1 if the specified regex matched any line
49+
# Returns nonzero exit code if end of stream was encountered
50+
function filter_game()
51+
{
52+
# Initially assume not found
53+
found=0
54+
55+
while read -r line
56+
do
57+
# Set found to 1 if the line matches the filter
58+
[[ $line =~ $1 ]] && found=1
59+
60+
# If line is blank, we have reached end of game attributes, but not eos, so return 0
61+
[[ -z $line ]] && return 0
62+
done
63+
64+
# If it gets here there is no more data, so return nonzero
65+
return 1
66+
}
67+
68+
69+
# Read all the lines of the PGN move list and concatenate them into the variable moves
70+
function read_moves()
71+
{
72+
# Clear the moves variable
73+
moves=''
74+
75+
while read -r line
76+
do
77+
# Quit if line is blank
78+
[[ -z $line ]] && return 0
79+
80+
# Append the line to moves with space in between
81+
moves="${moves} ${line}"
82+
83+
done
84+
85+
# Quit with failure return code here since read could not get another line
86+
return 1
87+
}
88+
89+
90+
# counts the number of moves in the moves list of a PGN format game
91+
# Assumes that "moves" is a string containing the complete moves list
92+
function count_moves()
93+
{
94+
# split moves into an array with the '.' as delimiter
95+
IFS='.'
96+
local moves_arr=( $moves )
97+
98+
# The second last entry contains the last moves index
99+
# Use the negative array index feature of bash to get it
100+
local second_last=${moves_arr[@]: -2 : 1}
101+
102+
# Now Second last contains something like "Kg1 Qg3+ 31" and the last word is the count
103+
IFS=' '
104+
local second_last_arr=( $second_last )
105+
106+
# Again use negative array index to get the number into num_moves
107+
num_moves=${second_last_arr[@]: -1 : 1}
108+
}
109+
110+
111+
# Display the indexes of all games that have a win in fewer than the specified moves
112+
function show_games_won_in()
113+
{
114+
local index=1
115+
116+
# While we have not reached the end of stream
117+
while filter_game '\[Result "(1-0|0-1)"\]'
118+
do
119+
# Check if this game has a result
120+
if [[ $found -eq 1 ]]
121+
then
122+
123+
# Read and count the moves
124+
read_moves
125+
count_moves
126+
127+
# Display the game index and moves if it has fewer than $1 moves
128+
[[ $num_moves -le $1 ]] && echo "Game $index: $num_moves moves" && echo "$moves" && echo
129+
130+
else # No result, skip over the moves list
131+
132+
read_chunk 0
133+
fi
134+
135+
# Increment the index
136+
index=$(( index + 1 ))
137+
done
138+
}
139+
140+
141+
getopts 'm:n:' opt
142+
143+
case $opt in
144+
m)
145+
echo Displaying games won in "$OPTARG" moves or less
146+
echo
147+
show_games_won_in "$OPTARG"
148+
;;
149+
150+
n)
151+
echo Displaying Game "#$OPTARG"
152+
echo
153+
show_nth_game "$OPTARG"
154+
;;
155+
esac
156+
157+
158+
159+
160+
161+
162+

0 commit comments

Comments
 (0)