Initial commit
[cartagena.git] / lib / cgi / .svn / text-base / cartagena-simple.rb.svn-base
1 #!/usr/bin/ruby -w
2 #
3 # == Synopsis
4 #
5 # Play one move of a Cartagena game
6 #
7 # == Usage
8 # CGI script
9 #
10 # == Author
11 # Neil Smith
12
13 require 'libcartagena'
14 require 'cgi'
15 require 'open3'
16 require 'timeout'
17
18 # Prevent dangerous operations
19 $SAFE = 1
20
21 class InvalidRobotError < StandardError
22 end
23
24 class NoInputFileError < StandardError
25 end
26
27 class InvalidMoveInHistoryError < StandardError
28 end
29
30 class GameWonInHistoryError < StandardError
31 end
32
33
34 # A table of the known game-playing robots
35
36 $ROBOT_NAME_TABLE = {
37 'First Possible' => '/var/www/scripts.njae.me.uk/cartagena/robots/1',
38 'Random' => '/var/www/scripts.njae.me.uk/cartagena/robots/2'
39 }
40
41 $ROBOT_CODE_TABLE = {
42 '1' => '/var/www/scripts.njae.me.uk/cartagena/robots/1',
43 '2' => '/var/www/scripts.njae.me.uk/cartagena/robots/2'
44 }
45
46
47 # How long the robot has to respond
48 $ROBOT_TIMEOUT = 15
49
50
51 def generate_output(cgi, returned_move, annotation)
52 if returned_move.empty?
53 return_part = ""
54 else
55 return_part = cgi.p { "Result is: " } + "\n" + cgi.h1 { returned_move } + "\n"
56 end
57
58 if annotation.empty?
59 annotation_part = ""
60 else
61 annotation_part = cgi.p { annotation }
62 end
63
64 cgi.html {
65 cgi.head { "\n" + cgi.title{"Move result"} } + "\n" +
66 cgi.body { return_part + annotation_part }
67 }
68 end
69
70
71 begin
72
73 cgi = CGI.new("html4")
74
75 chosen_robot = cgi['robot']
76 if $ROBOT_NAME_TABLE.has_key? chosen_robot
77 chosen_robot_dir = $ROBOT_NAME_TABLE[chosen_robot]
78 chosen_robot_dir.untaint
79 else
80 raise InvalidRobotError, "#{chosen_robot} is not a valid robot code"
81 end
82
83 begin
84 game, moves = Game.read_game(cgi['history'].downcase.split("\n"))
85 rescue InvalidMoveError => error
86 raise(InvalidMoveInHistoryError, error.message)
87 rescue GameWonNotice => error
88 raise(GameWonInHistoryError, error.message)
89 end
90
91 current_directory = Dir.pwd
92 current_directory.untaint
93 Dir.chdir chosen_robot_dir
94
95 returned_move = ""
96 returned_error = ""
97 robot_input = game.players.length.to_s + "\n"
98 robot_input += game.board.positions.collect {|p| p.symbol.to_s}.join("\n") + "\n"
99 robot_input += (moves.collect {|m| m.format(game.board, true)}).join("\n") + "\n" if not moves.empty?
100 robot_input += (game.current_player + 1).to_s + "\n"
101 robot_input += game.players_cards[game.current_player].collect {|c| c.to_s}.join("\n") + "\n" if not game.players_cards[game.current_player].empty?
102
103 # cgi.out { generate_output(cgi, "", "passing robot #{game.players.length.to_s + "#" + (moves.collect {|m| m.to_s}).join('!\n!') + "#" + next_roll.to_s}!") }
104 # cgi.out { generate_output(cgi, "", "passing robot #{robot_input}!") }
105
106
107 Timeout.timeout($ROBOT_TIMEOUT + 1) do
108 Open3.popen3('./runme') do |robot_in, robot_out, robot_err|
109 robot_in << robot_input
110 robot_in.close_write
111 returned_move = robot_out.gets
112 returned_error = robot_err.gets
113 end
114 end
115
116 Dir.chdir current_directory
117
118 # cgi.out { generate_output(cgi, "", "Returned move #{returned_move}; robot error was #{returned_error}!") }
119
120 raise(InvalidMoveError, "Robot returned error '#{returned_error}'") if returned_error != nil
121 raise(InvalidMoveError, "Null move") if returned_move.nil? or returned_move.empty?
122 next_move = returned_move.chomp.to_move(game, true)
123 game.apply_move! next_move
124
125 # cgi.out { generate_output(cgi, "", "Applied move #{returned_move}!") }
126 cgi.out { generate_output(cgi, returned_move, "") }
127
128 rescue InvalidMoveInHistoryError => error
129 cgi.out { generate_output(cgi, "", "Invalid move in history: #{error}") }
130 # puts "Invalid move in history: #{error}"
131 rescue GameWonInHistoryError => error
132 cgi.out { generate_output(cgi, "", "Game already won in historic moves: #{error}") }
133 # puts "Game already won in historic moves: #{error}"
134
135 rescue InvalidMoveError => error
136 cgi.out { generate_output(cgi, "", "Robot returned invalid move: #{error}") }
137 # puts "Robot returned invalid move: #{error}"
138 rescue GameWonNotice => error
139 cgi.out { generate_output(cgi, returned_move, "Game won: #{error}") }
140 # puts "Robot returned #{returned_move}"
141 # puts "Game won: #{error}"
142
143 rescue InvalidRobotError => error
144 cgi.out { generate_output(cgi, "", "Invalid robot selection: #{error}") }
145 # puts "Invalid robot selection: #{error}"
146 rescue Timeout::Error => error
147 cgi.out { generate_output(cgi, "", "Robot timed out") }
148 # puts "Robot timeout: #{error}"
149
150 end