acpc_dealer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. data/README.md +33 -0
  2. data/Rakefile +20 -0
  3. data/acpc_dealer.gemspec +29 -0
  4. data/bin/acpc_dealer +168 -0
  5. data/ext/hand_evaluator/extconf.rb +5 -0
  6. data/ext/hand_evaluator/hand_evaluator.c +38 -0
  7. data/lib/acpc_dealer/2p.limit.h5.r0.logs/2p.limit.h5.r0.actions.log +5 -0
  8. data/lib/acpc_dealer/2p.limit.h5.r0.logs/2p.limit.h5.r0.log +0 -0
  9. data/lib/acpc_dealer/dealer_runner.rb +72 -0
  10. data/lib/acpc_dealer/version.rb +3 -0
  11. data/lib/acpc_dealer.rb +33 -0
  12. data/lib/hand_evaluator.so +0 -0
  13. data/spec/coverage/assets/0.5.3/app.js +88 -0
  14. data/spec/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
  15. data/spec/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
  16. data/spec/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
  17. data/spec/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
  18. data/spec/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
  19. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
  20. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
  21. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
  22. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
  23. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
  24. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
  25. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
  26. data/spec/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
  27. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
  28. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
  29. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
  30. data/spec/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
  31. data/spec/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
  32. data/spec/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
  33. data/spec/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
  34. data/spec/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +363 -0
  35. data/spec/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  36. data/spec/coverage/assets/0.5.3/favicon_green.png +0 -0
  37. data/spec/coverage/assets/0.5.3/favicon_red.png +0 -0
  38. data/spec/coverage/assets/0.5.3/favicon_yellow.png +0 -0
  39. data/spec/coverage/assets/0.5.3/highlight.css +129 -0
  40. data/spec/coverage/assets/0.5.3/highlight.pack.js +1 -0
  41. data/spec/coverage/assets/0.5.3/jquery-1.6.2.min.js +18 -0
  42. data/spec/coverage/assets/0.5.3/jquery.dataTables.min.js +152 -0
  43. data/spec/coverage/assets/0.5.3/jquery.timeago.js +141 -0
  44. data/spec/coverage/assets/0.5.3/jquery.url.js +174 -0
  45. data/spec/coverage/assets/0.5.3/loading.gif +0 -0
  46. data/spec/coverage/assets/0.5.3/magnify.png +0 -0
  47. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  48. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  49. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  50. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  51. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  52. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  53. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  54. data/spec/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  55. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
  56. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  57. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
  58. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
  59. data/spec/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  60. data/spec/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  61. data/spec/coverage/assets/0.5.3/stylesheet.css +383 -0
  62. data/spec/coverage/index.html +81 -0
  63. data/spec/dealer_runner_spec.rb +83 -0
  64. data/spec/support/spec_helper.rb +33 -0
  65. data/vendor/project_acpc_server/LICENCE +23 -0
  66. data/vendor/project_acpc_server/Makefile +22 -0
  67. data/vendor/project_acpc_server/README +113 -0
  68. data/vendor/project_acpc_server/README.submission +42 -0
  69. data/vendor/project_acpc_server/acpc_play_match.pl +101 -0
  70. data/vendor/project_acpc_server/bm_server +0 -0
  71. data/vendor/project_acpc_server/bm_server.c +1557 -0
  72. data/vendor/project_acpc_server/bm_server.config +78 -0
  73. data/vendor/project_acpc_server/bm_widget +0 -0
  74. data/vendor/project_acpc_server/bm_widget.c +186 -0
  75. data/vendor/project_acpc_server/dealer +0 -0
  76. data/vendor/project_acpc_server/dealer.c +1278 -0
  77. data/vendor/project_acpc_server/evalHandTables +4269 -0
  78. data/vendor/project_acpc_server/example_player +0 -0
  79. data/vendor/project_acpc_server/example_player.c +204 -0
  80. data/vendor/project_acpc_server/example_player.limit.2p.sh +2 -0
  81. data/vendor/project_acpc_server/example_player.limit.3p.sh +2 -0
  82. data/vendor/project_acpc_server/example_player.nolimit.2p.sh +2 -0
  83. data/vendor/project_acpc_server/example_player.nolimit.3p.sh +2 -0
  84. data/vendor/project_acpc_server/game.c +1793 -0
  85. data/vendor/project_acpc_server/game.h +253 -0
  86. data/vendor/project_acpc_server/holdem.limit.2p.reverse_blinds.game +13 -0
  87. data/vendor/project_acpc_server/holdem.limit.3p.game +13 -0
  88. data/vendor/project_acpc_server/holdem.nolimit.2p.reverse_blinds.game +12 -0
  89. data/vendor/project_acpc_server/holdem.nolimit.3p.game +12 -0
  90. data/vendor/project_acpc_server/net.c +218 -0
  91. data/vendor/project_acpc_server/net.h +61 -0
  92. data/vendor/project_acpc_server/play_match.pl +99 -0
  93. data/vendor/project_acpc_server/protocol.odt +0 -0
  94. data/vendor/project_acpc_server/protocol.pdf +0 -0
  95. data/vendor/project_acpc_server/rng.c +138 -0
  96. data/vendor/project_acpc_server/rng.h +63 -0
  97. data/vendor/project_acpc_server/test.log +11 -0
  98. data/vendor/project_acpc_server/validate_submission.pl +546 -0
  99. metadata +315 -0
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # AcpcDealer
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'acpc_dealer'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install acpc_dealer
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Logging
24
+
25
+ For every match, two files will be logged: `<match name>.log` containing the match results and `<match name>.actions.log` containing the sequence of messages to and from the dealer over the course of the match. The location of these files can be customized with the :log_directory option. By default, they will be populated in the working directory of the calling process.
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/extensiontask'
4
+ require 'rake/testtask'
5
+
6
+ require File.expand_path('../lib/acpc_dealer/version', __FILE__)
7
+
8
+ Rake::ExtensionTask.new('hand_evaluator')
9
+
10
+ desc 'Build gem'
11
+ task :default => :build
12
+
13
+ task :build => :compile
14
+
15
+ Rake::TestTask.new do |t|
16
+ t.libs << "lib" << 'spec/support'
17
+ t.test_files = FileList['spec/**/*_spec.rb']
18
+ t.verbose = true
19
+ t.warning = true
20
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/acpc_dealer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "acpc_dealer"
6
+ gem.version = AcpcDealer::VERSION
7
+ gem.authors = ["Dustin Morrill"]
8
+ gem.email = ["morrill@ualberta.ca"]
9
+ gem.description = %q{Annual Computer Poker Competition Dealer}
10
+ gem.summary = %q{Ruby interface to the Annual Computer Poker Competition's dealer program.}
11
+ gem.homepage = "https://github.com/dmorrill10/acpc_dealer"
12
+
13
+ gem.add_dependency 'clive'
14
+ gem.add_dependency 'dmorrill10-utils', '~>1.0.0'
15
+ gem.add_dependency 'rake-compiler'
16
+
17
+ gem.add_development_dependency 'piston'
18
+
19
+ gem.add_development_dependency 'mocha'
20
+ gem.add_development_dependency 'simplecov'
21
+ gem.add_development_dependency 'turn'
22
+
23
+ gem.files = Dir.glob("lib/**/*") + Dir.glob("ext/**/*") + Dir.glob('*.gemspec') +
24
+ %w(Rakefile README.md) + Dir.glob('spec/**/*') + Dir.glob("vendor/**/*")
25
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
26
+ gem.extensions = Dir.glob("ext/**/extconf.rb")
27
+ gem.require_paths = ["lib"]
28
+ gem.executables << 'acpc_dealer'
29
+ end
data/bin/acpc_dealer ADDED
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dmorrill10-utils/process_runner'
4
+
5
+ require 'fileutils'
6
+
7
+ require 'clive'
8
+
9
+ require File.expand_path('../../lib/acpc_dealer', __FILE__)
10
+
11
+ class AcpcDealerCli < Clive
12
+
13
+ def self.print_usage(command_symbol)
14
+ puts AcpcDealerCli.find_command(command_symbol).help
15
+ exit
16
+ end
17
+
18
+ def self.game_def_from_components(number_of_players, betting_type)
19
+ begin
20
+ game_def = AcpcDealer::GAME_DEFINITION_FILE_PATHS[number_of_players][betting_type]
21
+ raise unless game_def
22
+ rescue
23
+ puts "Unable to find game definition for #{number_of_players} players with betting type '#{betting_type}'"
24
+ puts "Available game definitions:"
25
+ AcpcDealer::GAME_DEFINITION_FILE_PATHS.each do |num_players, game_defs|
26
+ game_defs.each do |type, path|
27
+ puts " #{num_players} #{type}"
28
+ end
29
+ end
30
+ exit
31
+ end
32
+
33
+ game_def
34
+ end
35
+
36
+ command :compile, 'Compiles the ACPC Dealer program' do
37
+ opt :c, :clean, 'Do a clean and full recompile' do
38
+ print 'Cleaning...'
39
+ FileUtils.cd AcpcDealer::DEALER_DIRECTORY do
40
+ system "make clean"
41
+ end
42
+ puts 'Done'
43
+ end
44
+
45
+ action do
46
+ print 'Compiling...'
47
+ FileUtils.cd AcpcDealer::DEALER_DIRECTORY do
48
+ system "make"
49
+ end
50
+ puts 'Done'
51
+ end
52
+ end
53
+
54
+ command :dealer, 'Runs the ACPC Dealer' do
55
+ desc 'The name of the match, defaults to <number_of_players>p.<betting_type>.h<hands>.r<random_seed>'
56
+ opt :m, :name, arg: '<name>', as: String
57
+
58
+ desc 'Parameters that determine which game definition to use'
59
+ opt :g, :game_def, args: '<number_of_players> <betting_type>', as: [Integer, Symbol]
60
+
61
+ opt :n, :hands, 'The number of hands to play', arg: '<hands>', as: Integer
62
+
63
+ desc 'The random seed to determine how the cards are dealt, defaults to a random random seed'
64
+ opt :r, :random_seed, arg: '<random_seed>', as: Integer
65
+
66
+ desc 'The names of the players participating in the match, defaults to "p1", "p2", ...'
67
+ opt :p, :player_names, args: '<p1_name>...', as: [String]
68
+
69
+ opt :l, :log_directory, 'Directory where logs will be placed', arg: '<log_directory>', as: String
70
+
71
+ opt :t_response, 'Maximum time per response', arg: '<t_response_milliseconds>', as: Integer
72
+
73
+ opt :t_hand, 'Maximum player time per hand', arg: '<t_hand_milliseconds>', as: Integer
74
+
75
+ opt :t_per_hand, 'Maximum average player time for match', arg: '<t_per_hand_milliseconds>', as: Integer
76
+
77
+ desc 'Maximum time to wait for players to connect, defaults to no timeout'
78
+ opt :start_timeout, arg: '<start_timeout_milliseconds>', as: Integer
79
+
80
+ action do
81
+ AcpcDealerCli.print_usage(:dealer) unless get(:game_def)
82
+ AcpcDealerCli.print_usage(:dealer) unless get(:hands)
83
+
84
+ (number_of_players, betting_type) = get(:game_def)
85
+ game_def = AcpcDealerCli.game_def_from_components(number_of_players, betting_type)
86
+
87
+ random_seed = if get(:random_seed)
88
+ get(:random_seed)
89
+ else
90
+ random_float = rand
91
+ (random_float * 10**random_float.to_s.length).to_i
92
+ end
93
+
94
+ name = if get(:name)
95
+ get(:name)
96
+ else
97
+ "#{number_of_players}p.#{betting_type}.h#{get(:hands)}.r#{random_seed}"
98
+ end
99
+
100
+ player_names = if get(:player_names)
101
+ get(:player_names)
102
+ else
103
+ []
104
+ end
105
+
106
+ while player_names.length < get(:game_def).first
107
+ player_names << "p#{player_names.length+1}"
108
+ end
109
+
110
+ arguments = {
111
+ match_name: name,
112
+ game_def_file_name: game_def,
113
+ hands: get(:hands).to_s,
114
+ random_seed: random_seed.to_s,
115
+ player_names: player_names.join(' ')
116
+ }
117
+
118
+ # Append to produce behavior of previous dealer version
119
+ options = ['-a']
120
+ options << "--t_response #{get(:t_response_milliseconds)}" if get(:t_response_milliseconds)
121
+ options << "--t_hand #{get(:t_hand_milliseconds)}" if get(:t_hand_milliseconds)
122
+ options << "--t_per_hand #{get(:t_per_hand_milliseconds)}" if get(:t_per_hand_milliseconds)
123
+ options << "--start_timeout #{get(:start_timeout_milliseconds)}" if get(:start_timeout_milliseconds)
124
+
125
+ arguments[:options] = options
126
+
127
+ AcpcDealerCli.run(['compile']) unless File.exists? AcpcDealer::DEALER_PATH
128
+
129
+ dealer_result = DealerRunner.start(arguments, get(:log_directory))
130
+ puts "Dealer pid: #{dealer_result[:pid]}, ports: #{dealer_result[:port_numbers].join(' ')}, log directory: #{dealer_result[:log_directory]}"
131
+ end
132
+ end
133
+
134
+ command :example_player, 'Starts an example player' do
135
+ desc 'Parameters that determine which type of player to use, same format as that for the dealer command'
136
+ opt :g, :game_def, args: '<number_of_players> <betting_type>', as: [Integer, Symbol]
137
+
138
+ desc 'The host name of the running dealer, defaults to "localhost"'
139
+ opt :o, :host_name, arg: '<host_name>', as: String
140
+
141
+ desc 'The port on which this player will try to connect to the dealer'
142
+ opt :p, :port, arg: '<port>', as: String
143
+
144
+ action do
145
+ AcpcDealerCli.print_usage(:example_player) unless get(:game_def)
146
+ AcpcDealerCli.print_usage(:example_player) unless get(:port)
147
+
148
+ (number_of_players, betting_type) = get(:game_def)
149
+ # Check that a game def for the specified parameters exists
150
+ AcpcDealerCli.game_def_from_components(number_of_players, betting_type)
151
+
152
+ host_name = if get(:host_name) then get(:host_name) else 'localhost' end
153
+
154
+ player = AcpcDealer::EXAMPLE_PLAYERS[number_of_players][betting_type]
155
+ players_directory = File.dirname(player)
156
+ FileUtils.cd players_directory
157
+ ProcessRunner.go [player, host_name, get(:port)]
158
+
159
+ puts "Example player for #{number_of_players} player #{betting_type}, connected to dealer on #{host_name}:#{get(:port)}"
160
+ end
161
+ end
162
+ end
163
+
164
+ if ARGV.empty?
165
+ puts AcpcDealerCli.help
166
+ else
167
+ AcpcDealerCli.run
168
+ end
@@ -0,0 +1,5 @@
1
+
2
+ #Run 'ruby -r mkmf extconf.rb' to generate a Makefile
3
+
4
+ require 'mkmf'
5
+ create_makefile("hand_evaluator")
@@ -0,0 +1,38 @@
1
+ // Ruby includes
2
+ #include <ruby.h>
3
+ #include <ruby/io.h>
4
+
5
+ // ACPC includes
6
+ #include "../../vendor/project_acpc_server/game.h"
7
+ #include "../../vendor/project_acpc_server/evalHandTables"
8
+
9
+ static VALUE cHandEvaluator;
10
+
11
+ /*
12
+ * @param [VALUE] self The class from which this method was called. This is
13
+ * an implicit argument.
14
+ * @param [VALUE] ruby_card_list The list of numeric ACPC represented cards in
15
+ * a Ruby array.
16
+ * @return [int] The rank of the hand.
17
+ */
18
+ static VALUE rank_hand(VALUE self, VALUE ruby_card_list) {
19
+ VALUE* card_list = RARRAY_PTR(ruby_card_list);
20
+ int card_list_length = RARRAY_LEN(ruby_card_list);
21
+
22
+ int card;
23
+ Cardset card_set = emptyCardset();
24
+
25
+ int i;
26
+ for(i = 0; i < card_list_length; ++i) {
27
+ card = NUM2INT(card_list[i]);
28
+ addCardToCardset(&card_set, suitOfCard(card),
29
+ rankOfCard(card));
30
+ }
31
+
32
+ return INT2NUM(rankCardset(card_set));
33
+ }
34
+
35
+ void Init_hand_evaluator() {
36
+ cHandEvaluator = rb_define_module("HandEvaluator");
37
+ rb_define_module_function(cHandEvaluator, "rank_hand", rank_hand, 1);
38
+ }
@@ -0,0 +1,5 @@
1
+ # name/game/hands/seed 2p.limit.h5.r0 /home/dmorrill/workspace/ualberta_poker_group/acpc_dealer/vendor/project_acpc_server/holdem.limit.2p.reverse_blinds.game 5 0
2
+ #--t_response 600000
3
+ #--t_hand 600000
4
+ #--t_per_hand 7000
5
+ Terminated
@@ -0,0 +1,72 @@
1
+
2
+ require 'socket'
3
+
4
+ require 'dmorrill10-utils/process_runner'
5
+
6
+ class DealerRunner
7
+
8
+ # @return [Array<Symbol>] The format of the dealer command. The symbols in this
9
+ # => array should correspond to those in the +dealer_arguments+ of ::start.
10
+ # => (see ::start)
11
+ DEALER_COMMAND_FORMAT = [
12
+ # @note The name of the match to start.
13
+ :match_name,
14
+ # @note The path of the game definition to use.
15
+ :game_def_file_name,
16
+ # @note The number of hands to play.
17
+ :hands,
18
+ # @note The random seed to use.
19
+ :random_seed,
20
+ # @note The names of the players in the game. Should be specified as a space delimited string of names.
21
+ :player_names,
22
+ # @note Should be specified as an option string that the dealer will understand.
23
+ :options
24
+ ]
25
+
26
+ # @param [Array] dealer_arguments Arguments to the new dealer instance.
27
+ # @param [String] log_directory The directory in which logs will be placed.
28
+ # => Defaults to +<dealer_arguments[:match_name]>.logs+.
29
+ # @param [Array] port_numbers The port numbers to which each player will connect.
30
+ # => Defaults to random.
31
+ # @return [Hash] The process ID of the started dealer (key +:pid+) and the array of ports that players may
32
+ # => use to connect to the new dealer instance (key +:port_numbers+).
33
+ # @raise (see ProcessRunner::go)
34
+ # @raise (see FileUtils::mkdir_p)
35
+ def self.start(dealer_arguments, log_directory=nil, port_numbers=nil)
36
+ dealer_start_command = DEALER_COMMAND_FORMAT.inject([AcpcDealer::DEALER_PATH]) do |command, parameter|
37
+ command << dealer_arguments[parameter].to_s
38
+ end
39
+ dealer_start_command << "-p #{port_numbers.join(',')}" if port_numbers
40
+
41
+ unless log_directory
42
+ log_directory = File.expand_path("../#{dealer_arguments[:match_name]}.logs", __FILE__)
43
+ end
44
+
45
+ FileUtils.mkdir_p log_directory
46
+
47
+ IO.pipe do |read_io, write_io|
48
+ pid = ProcessRunner.go(
49
+ dealer_start_command,
50
+ err: [
51
+ "#{dealer_arguments[:match_name]}.actions.log",
52
+ File::CREAT|File::WRONLY
53
+ ],
54
+ out: write_io,
55
+ chdir: log_directory
56
+ )
57
+
58
+ {pid: pid, port_numbers: read_io.gets.split, log_directory: log_directory}
59
+ end
60
+ end
61
+
62
+ # @todo How could ports be reserved without starting a server? Would +::ports_for_players+ even want to do that?
63
+
64
+ # @return [Array<Integer>] List of random open ports. Does NOT reserve the ports though,
65
+ # => so it's possible that the ports will come into use between calling this method and
66
+ # => using them.
67
+ def self.ports_for_players(number_of_players)
68
+ number_of_players.times.inject([]) do |ports, i|
69
+ ports << TCPServer.open('localhost', 0) { |s| s.addr[1] }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ module AcpcDealer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../hand_evaluator', __FILE__)
2
+ require File.expand_path("../acpc_dealer/dealer_runner", __FILE__)
3
+
4
+ module AcpcDealer
5
+ DEALER_DIRECTORY = File.expand_path('../../vendor/project_acpc_server', __FILE__)
6
+ GAME_DEFINITION_FILE_PATHS =
7
+ {
8
+ 2 =>
9
+ {
10
+ limit: "#{DEALER_DIRECTORY}/holdem.limit.2p.reverse_blinds.game",
11
+ nolimit: "#{DEALER_DIRECTORY}/holdem.nolimit.2p.reverse_blinds.game"
12
+ },
13
+ 3 =>
14
+ {
15
+ limit: "#{DEALER_DIRECTORY}/holdem.limit.3p.game",
16
+ nolimit: "#{DEALER_DIRECTORY}/holdem.nolimit.3p.game"
17
+ }
18
+ }
19
+ DEALER_PATH = "#{DEALER_DIRECTORY}/dealer"
20
+ EXAMPLE_PLAYERS =
21
+ {
22
+ 2 =>
23
+ {
24
+ limit: "#{DEALER_DIRECTORY}/example_player.limit.2p.sh",
25
+ nolimit: "#{DEALER_DIRECTORY}/example_player.nolimit.2p.sh"
26
+ },
27
+ 3 =>
28
+ {
29
+ limit: "#{DEALER_DIRECTORY}/example_player.limit.3p.sh",
30
+ nolimit: "#{DEALER_DIRECTORY}/example_player.nolimit.3p.sh"
31
+ }
32
+ }
33
+ end
Binary file
@@ -0,0 +1,88 @@
1
+ $(document).ready(function() {
2
+ // Configuration for fancy sortable tables for source file groups
3
+ $('.file_list').dataTable({
4
+ "aaSorting": [[ 1, "asc" ]],
5
+ "bPaginate": false,
6
+ "bJQueryUI": true,
7
+ "aoColumns": [
8
+ null,
9
+ { "sType": "percent" },
10
+ null,
11
+ null,
12
+ null,
13
+ null,
14
+ null
15
+ ]
16
+ });
17
+
18
+ // Syntax highlight all files up front - deactivated
19
+ // $('.source_table pre code').each(function(i, e) {hljs.highlightBlock(e, ' ')});
20
+
21
+ // Syntax highlight source files on first toggle of the file view popup
22
+ $("a.src_link").click(function() {
23
+ // Get the source file element that corresponds to the clicked element
24
+ var source_table = $($(this).attr('href'));
25
+
26
+ // If not highlighted yet, do it!
27
+ if (!source_table.hasClass('highlighted')) {
28
+ source_table.find('pre code').each(function(i, e) {hljs.highlightBlock(e, ' ')});
29
+ source_table.addClass('highlighted');
30
+ };
31
+ });
32
+
33
+ // Set-up of popup for source file views
34
+ $("a.src_link").fancybox({
35
+ 'hideOnContentClick': true,
36
+ 'centerOnScroll': true,
37
+ 'width': '90%',
38
+ 'padding': 0,
39
+ 'transitionIn': 'elastic'
40
+ });
41
+
42
+ // Hide src files and file list container after load
43
+ $('.source_files').hide();
44
+ $('.file_list_container').hide();
45
+
46
+ // Add tabs based upon existing file_list_containers
47
+ $('.file_list_container h2').each(function(){
48
+ var container_id = $(this).parent().attr('id');
49
+ var group_name = $(this).find('.group_name').first().html();
50
+ var covered_percent = $(this).find('.covered_percent').first().html();
51
+
52
+ $('.group_tabs').append('<li><a href="#' + container_id + '">' + group_name + ' ('+ covered_percent +')</a></li>');
53
+ });
54
+
55
+ $('.group_tabs a').each( function() {
56
+ $(this).addClass($(this).attr('href').replace('#', ''));
57
+ });
58
+
59
+ // Make sure tabs don't get ugly focus borders when active
60
+ $('.group_tabs a').live('focus', function() { $(this).blur(); });
61
+
62
+ var favicon_path = $('link[rel="shortcut icon"]').attr('href');
63
+ $('.group_tabs a').live('click', function(){
64
+ if (!$(this).parent().hasClass('active')) {
65
+ $('.group_tabs a').parent().removeClass('active');
66
+ $(this).parent().addClass('active');
67
+ $('.file_list_container').hide();
68
+ $(".file_list_container" + $(this).attr('href')).show();
69
+ window.location.href = window.location.href.split('#')[0] + $(this).attr('href').replace('#', '#_');
70
+
71
+ // Force favicon reload - otherwise the location change containing anchor would drop the favicon...
72
+ // Works only on firefox, but still... - Anyone know a better solution to force favicon on local file?
73
+ $('link[rel="shortcut icon"]').remove();
74
+ $('head').append('<link rel="shortcut icon" type="image/png" href="'+ favicon_path +'" />');
75
+ };
76
+ return false;
77
+ });
78
+
79
+ if (jQuery.url.attr('anchor')) {
80
+ $('.group_tabs a.'+jQuery.url.attr('anchor').replace('_', '')).click();
81
+ } else {
82
+ $('.group_tabs a:first').click();
83
+ };
84
+
85
+ $("abbr.timeago").timeago();
86
+ $('#loading').fadeOut();
87
+ $('#wrapper').show();
88
+ });