nim 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.komodoproject
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nim.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = Nim
2
+
3
+ 分成几摊的豆子,两个玩家轮流拣,一次可拿任意一摊里的至少一颗,拣掉最后一粒豆子的玩家判负。
4
+
5
+ You and Q take turns nim beans from distinct heaps,
6
+ On each turn, you must nim at least one bean, and may nim any number of beans provided they all come from the same heap.
7
+
8
+ Whom nim the last one bean were *lost*
9
+
10
+ == Playing
11
+
12
+ gem install nim
13
+
14
+ nim
15
+
16
+ == Authors
17
+
18
+ * {Takafan}[http://hululuu.com]
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/nim ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_path = File.expand_path('../../lib', __FILE__)
4
+ $:.unshift(lib_path)
5
+ require 'nim'
6
+ require 'nim/version'
7
+
8
+ begin
9
+ raise Nim::VERSION if ['--version', '-v'].include? ARGV[0]
10
+
11
+ Nim::Nim.new
12
+
13
+ rescue Exception => e
14
+ print "#{e.class}: " unless e.class == RuntimeError
15
+ puts "#{e.message}"
16
+ exit 1
17
+ end
data/lib/nim.rb ADDED
@@ -0,0 +1 @@
1
+ require 'nim/nim_core'
@@ -0,0 +1,253 @@
1
+ module Nim
2
+ class Nim
3
+
4
+ #游戏规则:分成几摊的豆子,两个玩家轮流拣,一次可拿任意一摊里的至少一颗,拣掉最后一粒豆子的玩家判负。
5
+
6
+ def initialize
7
+ puts %q{
8
+ You and Q take turns nim beans from distinct heaps,
9
+ On each turn, you must nim at least one bean, and may nim any number of beans provided they all come from the same heap.
10
+
11
+ Whom nim the last one bean were *lost*
12
+
13
+ }
14
+
15
+ a = [1,3,5,7]
16
+ b = [3,4,5,6]
17
+ puts "heap 1 (#{a.inject{|x, sum| x + sum}} beans)"
18
+ draw0(a)
19
+ puts "heap 2 (#{b.inject{|x, sum| x + sum}} beans)"
20
+ draw0(b)
21
+
22
+ loop do
23
+ print 'choose the heap 1/2: '
24
+ heap = gets.to_i
25
+ if [1,2].include?(heap)
26
+ @mat = heap == 1 ? a : b
27
+ break
28
+ end
29
+ puts %q{ inputs: 1 or 2
30
+ }
31
+ end
32
+
33
+ init_unsafe_positions
34
+
35
+ hand = 1
36
+
37
+ loop do
38
+ print 'nim first or second 1/2: '
39
+ g = gets
40
+ if g.strip == "unsafe"
41
+ @unsafe_positions.each{|x| puts x.join ' '}
42
+ draw_mat
43
+ else
44
+ hand = g.to_i
45
+ break if [1,2].include?(hand)
46
+ puts %q{ inputs: 1 or 2
47
+ }
48
+ end
49
+ end
50
+ puts
51
+
52
+ ai_pick if hand == 2
53
+
54
+ loop do
55
+
56
+ loop do
57
+ print 'you nim: '
58
+ args = gets.split ' '
59
+
60
+ if args.size == 1
61
+ iarg0 = args[0].to_i
62
+
63
+ if iarg0 > 0 and iarg0 < 10 #4
64
+ pos = iarg0 - 1
65
+ if (0...@mat.size).include?(pos) and @mat[pos] > 0
66
+ pick(pos)
67
+ break
68
+ end
69
+ elsif iarg0 > 10 and iarg0 < 100 #45
70
+ pos = iarg0 / 10 - 1
71
+ num = iarg0 % 10
72
+ if (0...@mat.size).include?(pos) and num > 0 and @mat[pos] >= num
73
+ pick(pos, num)
74
+ break
75
+ end
76
+ end
77
+
78
+ elsif args.size == 2
79
+ iarg0 = args[0].to_i
80
+ iarg1 = args[1].to_i
81
+
82
+ if iarg0 > 0 and iarg0 < 10 and iarg1 > 0 and iarg1 < 10 #4 5
83
+ pos = iarg0 -1
84
+ num = iarg1
85
+ if (0...@mat.size).include?(pos) and @mat[pos] >= num
86
+ pick(pos, num)
87
+ break
88
+ end
89
+ end
90
+ end
91
+ puts %q{ invalid inputs.
92
+ nim least 1 beans from a line.
93
+ nim 5 beans from line 4, inputs: 45 or 4 5
94
+ nim all beans from line 4, inputs: 4
95
+ }
96
+ end
97
+
98
+ if @mat == [0,0,0,0]
99
+ puts 'you *LOSE* :('
100
+ break
101
+ end
102
+
103
+ ai_pick
104
+ if @mat == [0,0,0,0]
105
+ puts 'you *WIN* :)'
106
+ break
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+
113
+ def ai_pick
114
+ #行动集
115
+ actions = Hash.new
116
+
117
+ @unsafe_positions.each do |unsafe|
118
+ dup = unsafe.dup
119
+
120
+ scoped_index = 0
121
+ scoped_value = 0
122
+
123
+ @mat.each_with_index do |x, i|
124
+ idx = dup.index(x)
125
+ if idx
126
+ dup.delete_at(idx)
127
+ else
128
+ #暂记不相等的value和它的下标
129
+ scoped_index = i
130
+ scoped_value = x
131
+ end
132
+ end
133
+
134
+ if dup.size == 1 and scoped_value > dup.first
135
+ actions[scoped_index] = scoped_value - dup.shift
136
+ end
137
+ end
138
+
139
+ #拣取的下标和数量
140
+ pos = num = 0
141
+
142
+ if actions.size > 0
143
+ #随机挑一个候选执行
144
+ keys = actions.keys
145
+ pos = keys[Random.new.rand(0...keys.size)]
146
+ num = actions[pos]
147
+ else
148
+ #值不为0的下标集
149
+ pos_ex = []
150
+ @mat.each_with_index do |x, i|
151
+ pos_ex << i if x > 0
152
+ end
153
+
154
+ #从不为0的堆中随机找一堆,随机拣取n颗
155
+ pos = pos_ex[Random.new.rand(0...pos_ex.size)]
156
+ num = Random.new.rand(1..@mat[pos])
157
+ end
158
+
159
+ puts "Q nim: #{(pos + 1) * 10 + num}"
160
+ pick(pos, num)
161
+ end
162
+
163
+
164
+ def pick(pos, num=@mat[pos])
165
+ @mat[pos] -= num
166
+ puts
167
+ draw_mat
168
+ end
169
+
170
+
171
+ def draw_mat
172
+ draw(@mat)
173
+ end
174
+
175
+
176
+ def draw(mat)
177
+ graph = ''
178
+ space = ' '
179
+ dot = '.'
180
+
181
+ mat.each_with_index do |c, i|
182
+ graph << "#{space * 4} #{i + 1} #{space * (3 - i)} #{(dot + space) * c} \n"
183
+ end
184
+
185
+ puts "#{graph}\n"
186
+ end
187
+
188
+
189
+ def draw0(mat)
190
+ graph = ''
191
+ space = ' '
192
+ dot = '.'
193
+
194
+ mat.each_with_index do |c, i|
195
+ graph << "#{space * 4} #{space * (3 - i)} #{(dot + space) * c} \n"
196
+ end
197
+
198
+ puts "#{graph}\n"
199
+ end
200
+
201
+
202
+ def init_unsafe_positions
203
+ @unsafe_positions = []
204
+ #初始化阵集
205
+ arr = []
206
+ for a in 0..@mat[0]
207
+ for b in a..@mat[1]
208
+ for c in b..@mat[2]
209
+ for d in c..@mat[3]
210
+ arr << [a, b, c, d]
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ #remove [0,0,0,0]
217
+ arr.shift
218
+
219
+ #first unsafe-position is [0,0,0,1]
220
+ @unsafe_positions << arr.shift
221
+
222
+ #从小到大遍历阵集,增加unsafe
223
+ arr.each do |sample|
224
+ is_safe = false
225
+
226
+ @unsafe_positions.each do |unsafe|
227
+
228
+ dup = unsafe.dup
229
+ sample.each_with_index do |x, i|
230
+ j = dup.index(x)
231
+ dup.delete_at(j) if j
232
+ end
233
+
234
+ #有一堆豆子数不相等(多出) => 可以拿成一种unsafe => 是安全的
235
+ if dup.size == 1
236
+ is_safe = true
237
+ break
238
+ end
239
+ end
240
+
241
+ @unsafe_positions << sample unless is_safe
242
+ end
243
+
244
+ puts
245
+ draw_mat
246
+ end
247
+
248
+ def gets
249
+ STDIN.gets
250
+ end
251
+
252
+ end
253
+ end
@@ -0,0 +1,3 @@
1
+ module Nim
2
+ VERSION = "0.1.1"
3
+ end
data/nim.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "nim/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "nim"
7
+ s.version = Nim::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["takafan"]
10
+ s.email = ["takafan@163.com"]
11
+ s.homepage = "http://github.com/takafan/nim"
12
+ s.summary = %q{Nim}
13
+ s.description = %q{play nim game with Q, Whom nim the last one bean were *lost*}
14
+
15
+ s.rubyforge_project = "nim"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nim
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - takafan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-17 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: play nim game with Q, Whom nim the last one bean were *lost*
15
+ email:
16
+ - takafan@163.com
17
+ executables:
18
+ - nim
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - README.rdoc
25
+ - Rakefile
26
+ - bin/nim
27
+ - lib/nim.rb
28
+ - lib/nim/nim_core.rb
29
+ - lib/nim/version.rb
30
+ - nim.gemspec
31
+ homepage: http://github.com/takafan/nim
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project: nim
51
+ rubygems_version: 1.7.2
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Nim
55
+ test_files: []