def set_problem(self, problem): self.__Problem = problem # サイズを計算する. # ブロックの最大幅と最大高さを求め, # すべてのブロックにそのサイズの矩形を割り当てる. max_width = 3 max_height = 3 for block in problem.block_list: if max_width < block.width: max_width = block.width if max_height < block.height: max_height = block.height self.__WidthUnit = max_width + 1 self.__HeightUnit = max_height + 1 # ブロック数の平方をもとめ,それを行数,列数にする. # もちろん,その値を切り上げた整数値を求める. n = problem.block_num ncols = m.ceil(m.sqrt(n)) nrows = (n + ncols - 1) // ncols self.set_size(ncols * self.__WidthUnit, nrows * self.__HeightUnit) # 各ブロックの配置位置を計算する. self.__BlockPosDict = dict() x_pos = 0 y_pos = 0 for block in problem.block_list: x1 = x_pos * self.__WidthUnit y1 = y_pos * self.__HeightUnit self.__BlockPosDict[block.block_id] = Position(x1, y1) x_pos += 1 if x_pos == ncols: x_pos = 0 y_pos += 1
def paintEvent(self, event): painter = self.draw_init() painter.save() # ブロックの描画 for block in self.__Problem.block_list: p0 = self.__BlockPosDict[block.block_id] # ブロックの実際の大きさを考慮して配置位置を補正する. dx = ((self.__WidthUnit - block.width) / 2) * self.grid_size dy = (self.__HeightUnit - block.height - 1) * self.grid_size pos0 = self.pos_to_local(p0) + self.base_pos pos0 += QPointF(dx, dy) self.draw_block(painter, block, pos0) # ブロック番号の描画 self.set_text_pen(painter) p1 = p0 + Position(0, self.__HeightUnit - 1) pos1 = self.pos_to_local(p1) + self.base_pos w1 = self.__WidthUnit * self.grid_size h1 = self.grid_size painter.drawText(QRect(pos1.x(), pos1.y(), w1, h1), Qt.AlignCenter, 'BLOCK#{}'.format(block.block_id)) painter.restore()
def transact_position(self, action, ticker, quantity, price, commission): """ Handles any new position or modification to a current position, by calling the respective _add_position and _modify_position methods. Hence, this single method will be called by the PortfolioHandler to update the Portfolio itself. """ if action == "BOT": self.cur_cash -= ((quantity * price) + commission) elif action == "SLD": self.cur_cash += ((quantity * price) - commission) if ticker not in self.positions: # self._add_position( # action, ticker, quantity, # price, commission # ) position = Position(ticker, action, quantity, price, commission) self.positions[ticker] = position else: # self._modify_position( # action, ticker, quantity, # price, commission # ) self.positions[ticker].transact_shares(action, quantity, price, commission) self.update_portfolio()
def make_segment_list(block): grid_set = set() for pos in block.pos_list: grid_set.add(pos) segment_dict = dict() dpos_n = Position(0, -1) dpos_e = Position(1, 0) dpos_s = Position(0, 1) dpos_w = Position(-1, 0) dpos_se = Position(1, 1) for pos in block.pos_list: pos_n = pos.adjacent_pos('n') pos_e = pos.adjacent_pos('e') pos_s = pos.adjacent_pos('s') pos_w = pos.adjacent_pos('w') pos_se = pos_s.adjacent_pos('e') if pos_n not in grid_set: segment_dict[pos] = (pos_e, 'n') if pos_e not in grid_set: segment_dict[pos_e] = (pos_se, 'e') if pos_s not in grid_set: segment_dict[pos_se] = (pos_s, 's') if pos_w not in grid_set: segment_dict[pos_s] = (pos, 'w') # segment_dict の要素を一つ取り出す. for first_pos, (last_pos, dlabel) in segment_dict.items(): break else: assert False segment_list = list() dlabel0 = dlabel while True: pos1, dlabel1 = segment_dict[last_pos] d = make_dir(dlabel, dlabel1) if d is not None: segment_list.append((last_pos, d)) if pos1 == first_pos: break last_pos = pos1 dlabel = dlabel1 d = make_dir(dlabel0, dlabel1) segment_list.append((first_pos, d)) return segment_list
def get_call_history(hands, board_number): call_history = CallHistory([], Position.from_index((board_number + 3) % 4), Vulnerability.from_board_number(board_number)) while len(call_history.calls) < 4 or not call_history.is_complete(): whos_turn = call_history.position_to_call().index call = kbb_bidder.find_call_for(hands[whos_turn], call_history) or Pass() call_history.calls.append(call) return call_history
def print(self, *, fout=sys.stdout): fout.write('SIZE {}X{}\n'.format(self.width, self.height)) for y in range(self.height): for x in range(self.width): if x > 0: fout.write(',') fout.write('{:2d}'.format(self.label(Position(x, y)))) fout.write('\n') for block_id in sorted(self.__block_pos_dict.keys()): pos = self.block_pos(block_id) fout.write('BLOCK#{} @{}\n'.format(block_id, pos))
def label(self, *args): if len(args) == 1 and isinstance(args[0], Position): pos = args[0] elif len(args) == 2 and isinstance(args[0], int) and isinstance( args[1], int): pos = Position(args[0], args[1]) else: print( 'Error in Ansswer.label(args): args must be Position or (int, int)' ) assert False index = self.__pos_to_index(pos) return self.__label_array[index]
def __init__(self, solver, problem, width, height): self.__solver = solver self.__problem = problem self.__width = width self.__height = height self.__gridpos_list = list() for y in range(self.__height): for x in range(self.__width): self.__gridpos_list.append(Position(x, y)) self.__x_var_dict = dict() self.__y_var_dict = dict() self.__g_var_dict = dict() self.__b_var_dict = dict() self.__l_var_dict = dict() self.__t_var_dict = dict() self.__e_var_dict = dict()
def read_BLOCK2(self): stat = self.readline() if not stat: self.error('[A6] syntax error') return 0, None # BLOCK行のパタンにマッチするか調べる. m = self.__pBLOCK2.match(self.__cur_line) if m is None: # マッチしなかった self.error('[A7] syntax error') return 0, None block_id = int(m.group(1)) x = int(m.group(2)) y = int(m.group(3)) return block_id, Position(x, y)
def read_answer(self, fin, block_num): self.__in = fin self.__nerr = 0 self.__cur_lineno = 0 if not self.readline(): self.error('[A1] syntax error') return None p = self.read_SIZE2() if p is None: self.error("[A2] 'SIZE' expected") return None width, height = p answer = Answer(width, height) label_array = [0 for i in range(width * height)] for y in range(height): stat = self.readline() if not stat: self.error("[A3] syntax error") return None pat_list = self.__cur_line.split(',') if len(pat_list) != width: self.error("[A4] syntax error") return None for x in range(width): pat = pat_list[x].rstrip().lstrip() if pat != '+': label = int(pat) answer.set_label(Position(x, y), label) for block_id in range(1, block_num + 1): act_block_id, pos = self.read_BLOCK2() if not pos: return None if act_block_id != block_id: self.error('[A5] wrong BLOCK#, {} expected.'.format(block_id)) return None answer.set_block_pos(block_id, pos) return answer
def print_block(block, fout): w = block.width h = block.height fout.write('BLOCK#{} {}X{}\n'.format(block.block_id, w, h)) for y in range(h): first = True for x in range(w): if first: first = False else: fout.write(',') pos = Position(x, y) l = block.label(pos) if l == -1: # 範囲外 fout.write(' 0') elif l == 0: # 範囲内だけどラベルなし fout.write(' +') else: fout.write('{:2d}'.format(l)) fout.write('\n')
def get_answer(self, model): ans = Answer(self.__width, self.__height) # ブロック位置を得る. for block_id in self.__problem.block_id_list: for x in range(self.__width): var = self.__block_x_var(block_id, x) if model[var] == SatBool3.TRUE: break else: assert False for y in range(self.__height): var = self.__block_y_var(block_id, y) if model[var] == SatBool3.TRUE: break else: assert False ans.set_block_pos(block_id, Position(x, y)) # 線分ラベルを得る. # 基本的には self.__l_var_dict に入っている線分番号用の # 変数の値を読めばよいが,SAT問題の都合上,線分でない # 部分にも非0の値がつくことがあるので端子間を結ぶ # 線分を取り出す. for line_id in self.__problem.line_id_list: (block_id1, pos1), (block_id2, pos2) = self.__problem.terminals(line_id) gpos1 = ans.block_pos(block_id1) + pos1 gpos2 = ans.block_pos(block_id2) + pos2 route = self.__get_route(model, gpos1, gpos2, line_id) for pos in route: key = pos, line_id var = self.__l_var_dict[key] assert model[var] == SatBool3.TRUE ans.set_label(pos, line_id) return ans
def update_positions_from_fill(self, fill): fill_dir = self.get_fill_direction_koeficient(fill) quantity = fill_dir * fill.quantity # Update positions list with new quantities position = self.get_current_position(fill.symbol) if position is None: position = Position(fill.symbol, fill.trade_id, quantity) else: position.set_quantity(position.get_quantity() + quantity) if position.get_quantity() == 0: self.current_positions[fill.symbol] = None else: self.current_positions[fill.symbol] = position
def get(self): bidder = Bidder() board = self._board_from_request() until_position_string = self.request.get('until_position') until_position = Position.from_char(until_position_string) if until_position_string else None call_selections = self._bid_all_hands(bidder, board, until_position=until_position) until_position_history_string = board.call_history.calls_string() call_selections += self._bid_all_hands(bidder, board) # Callers might want to know what the full history would look like if autobid. board_dict = { 'board_number': board.number, 'calls_string': until_position_history_string, # The history up to "until_position" 'autobid_continuation': board.call_history.calls_string(), # How the autobidder would continue 'autobid_interpretations': map(self._json_tuple, call_selections), # Interpretations for all calls (including continuation) } self.response.headers["Content-Type"] = "application/json" self.response.headers["Cache-Control"] = "public" expires_date = datetime.datetime.utcnow() + datetime.timedelta(days=1) expires_str = expires_date.strftime("%d %b %Y %H:%M:%S GMT") self.response.headers.add_header("Expires", expires_str) self.response.out.write(json.dumps(board_dict))
def read_BLOCK(self): # BLOCK行のパタンにマッチするか調べる. m = self.__pBLOCK.match(self.__cur_line) if m is None: # マッチしなかった return False block_id = int(m.group(1)) block_width = int(m.group(2)) block_height = int(m.group(3)) pos_list = list() label_dict = dict() for y in range(block_height): line = self.__in.readline() pat_list = line.split(',') if len(pat_list) != block_width: self.error("# of block patterns mismach.") return True for x in range(block_width): pat = (pat_list[x].rstrip()).lstrip() if pat == '+': # ラベルなしの値を 0 にすればよかったのに label = 0 else: label = int(pat) if label == 0: # こちらは領域外.こっちを0以外の記号にしたらよかった. continue pos = Position(x, y) pos_list.append(pos) label_dict[pos] = label self.__problem.add_block(block_id, pos_list, label_dict) return True
def block_type(pat) : I_pat_list = [ [ Position(0, 0), Position(0, 1), Position(0, 2), Position(0, 3) ], [ Position(0, 0), Position(1, 0), Position(2, 0), Position(3, 0) ] ] O_pat_list = [ [ Position(0, 0), Position(1, 0), Position(0, 1), Position(1, 1) ] ] T_pat_list = [ [ Position(1, 0), Position(0, 1), Position(1, 1), Position(2, 1) ], [ Position(1, 0), Position(0, 1), Position(1, 1), Position(1, 2) ], [ Position(0, 0), Position(1, 0), Position(2, 0), Position(1, 1) ], [ Position(0, 0), Position(0, 1), Position(1, 1), Position(0, 2) ] ] J_pat_list = [ [ Position(1, 0), Position(1, 1), Position(0, 2), Position(1, 2) ], [ Position(0, 0), Position(0, 1), Position(1, 1), Position(2, 1) ], [ Position(0, 0), Position(1, 0), Position(0, 1), Position(0, 2) ], [ Position(0, 0), Position(1, 0), Position(2, 0), Position(2, 1) ] ] L_pat_list = [ [ Position(0, 0), Position(0, 1), Position(0, 2), Position(1, 2) ], [ Position(0, 0), Position(1, 0), Position(2, 0), Position(0, 1) ], [ Position(0, 0), Position(1, 0), Position(1, 1), Position(1, 2) ], [ Position(2, 0), Position(0, 1), Position(1, 1), Position(2, 1) ] ] S_pat_list = [ [ Position(1, 0), Position(2, 0), Position(0, 1), Position(1, 1) ], [ Position(0, 0), Position(0, 1), Position(1, 1), Position(1, 2) ] ] Z_pat_list = [ [ Position(0, 0), Position(1, 0), Position(1, 1), Position(2, 1) ], [ Position(1, 0), Position(0, 1), Position(1, 1), Position(0, 2) ] ] for I_pat in I_pat_list : if pat == I_pat : return 'I' for O_pat in O_pat_list : if pat == O_pat : return 'O' for T_pat in T_pat_list : if pat == T_pat : return 'T' for J_pat in J_pat_list : if pat == J_pat : return 'J' for L_pat in L_pat_list : if pat == L_pat : return 'L' for S_pat in S_pat_list : if pat == S_pat : return 'S' for Z_pat in Z_pat_list : if pat == Z_pat : return 'Z' return 'X'
def gen_routing_constraint(self): # 盤面上の線分ラベルを表す変数を作る. # 一つのグリッドに対して線分数の数だけ用意する. for pos in self.__gridpos_list: var_list = list() for line_id in self.__problem.line_id_list: var = self.__solver.new_variable() key = pos, line_id self.__l_var_dict[key] = var var_list.append(var) # 一つのグリッド上では高々1つの線分しか選ばれない. # 一つも選ばれない場合もあるので one-hot ではない. self.__gen_at_most_one_constraint(var_list) # このグリッドがブロックに覆われている(線分として使えない)時に # True となる変数. b_var = self.__b_var_dict[pos] # pos にいずれかの端子が置かれる時に True になる変数. t_all_var = self.__solver.new_variable() self.__t_var_dict[pos] = t_all_var t_var_list = list() for line_id in self.__problem.line_id_list: # pos に line_id の端子が置かれる時に True になる変数 t1_var = self.__solver.new_variable() key = pos, line_id xyvar_list = list() for block_id, pos1 in self.__problem.terminals(line_id): pos0 = pos - pos1 if pos0.is_in_range(self.__width, self.__height): # block_id のブロックが pos0 に置かれた時に # pos のグリッドが line_id の線分の端子となる. x_var = self.__block_x_var(block_id, pos0.x) y_var = self.__block_y_var(block_id, pos0.y) xyvar_list.append((x_var, y_var)) n = len(xyvar_list) if n == 0: self.__solver.add_clause(-t1_var) elif n == 1: x_var, y_var = xyvar_list[0] self.__solver.add_clause(-x_var, -y_var, t1_var) self.__solver.add_clause(x_var, -t1_var) self.__solver.add_clause(y_var, -t1_var) elif n == 2: var_list = list() for x_var, y_var in xyvar_list: var = self.__solver.new_variable() self.__solver.add_clause(-x_var, -y_var, var) self.__solver.add_clause(x_var, -var) self.__solver.add_clause(y_var, -var) var_list.append(var) var1, var2 = var_list self.__solver.add_clause(-var1, t1_var) self.__solver.add_clause(-var2, t1_var) self.__solver.add_clause(var1, var2, -t1_var) # t1_var が True の時には線分番号 line_id のラベルがつく. l_var = self.__line_var(pos, line_id) self.__solver.add_clause(-t1_var, l_var) # t1_var が True の時には pos に端子が置かれる. self.__solver.add_clause(-t1_var, t_all_var) t_var_list.append(t1_var) # t_var が True の時,t_var_list の中の1つは必ず True となる. self.__solver.add_clause(-t_all_var, t_var_list) # t_all_var が False で b_var が True の場合線分ラベルは 0 となる. for line_id in self.__problem.line_id_list: l_var = self.__line_var(pos, line_id) self.__solver.add_clause(t_all_var, -b_var, -l_var) # グリッド間の枝を表す変数を作る. self.__e_var_dict = dict() # 縦方向の枝 for x in range(self.__width): for y in range(self.__height - 1): var = self.__solver.new_variable() # (x, y) から s 方向の枝という意味 key = Position(x, y), 's' self.__e_var_dict[key] = var # (x, y + 1) から n 方向の枝という意味 key = Position(x, y + 1), 'n' self.__e_var_dict[key] = var # 横方向の枝 for y in range(self.__height): for x in range(self.__width - 1): var = self.__solver.new_variable() # (x, y) から e 方向の枝という意味 key = Position(x, y), 'e' self.__e_var_dict[key] = var # (x + 1, y) から w 方向の枝という意味 key = Position(x + 1, y), 'w' self.__e_var_dict[key] = var # 各グリッドに接続する枝に関する制約を作る. for pos in self.__gridpos_list: var_list = list() for dir in ('n', 'e', 's', 'w'): key = pos, dir if key not in self.__e_var_dict: continue var = self.__e_var_dict[key] var_list.append(var) t_var = self.__t_var_dict[pos] b_var = self.__b_var_dict[pos] # pos が線分の端子の場合 # 1個の変数が選ばれる. self.__gen_one_hot_constraints_with_cond(var_list, t_var) # pos が端子以外のブロックの場合, # 変数は選ばれない. for var in var_list: self.__solver.add_clause(-b_var, t_var, -var) # pos がそれ以外の場合 # 0 個か 2 個の変数が選ばれる. self.__gen_zero_or_two_hot_constraints_with_cond(var_list, -b_var) # 枝が選択されている時にその両端のグリッドの線分番号が等しくなるという制約 for pos1 in self.__gridpos_list: for dir in ('n', 'e', 's', 'w'): key = pos1, dir if key not in self.__e_var_dict: continue e_var = self.__e_var_dict[key] pos2 = pos1.adjacent_pos(dir) for line_id in self.__problem.line_id_list: l1_var = self.__line_var(pos1, line_id) l2_var = self.__line_var(pos2, line_id) self.__solver.add_clause(-e_var, l1_var, -l2_var) self.__solver.add_clause(-e_var, -l1_var, l2_var) # コの字制約を作る. for pos in self.__gridpos_list: key1 = pos, 's' if key1 not in self.__e_var_dict: continue e1_var = self.__e_var_dict[key1] key2 = pos, 'e' if key2 not in self.__e_var_dict: continue e2_var = self.__e_var_dict[key2] pos2 = pos + Position(0, 1) key3 = pos2, 'e' e3_var = self.__e_var_dict[key3] pos3 = pos + Position(1, 0) key4 = pos3, 's' e4_var = self.__e_var_dict[key4] # e1, e2, e3, e4 のうち3つ以上同時に true にならない. self.__solver.add_clause(-e1_var, -e2_var, -e3_var) self.__solver.add_clause(-e1_var, -e2_var, -e4_var) self.__solver.add_clause(-e1_var, -e3_var, -e4_var) self.__solver.add_clause(-e2_var, -e3_var, -e4_var)
game = ColorFight(url_host, game_id, user_name) game.connect() if game.register(): while True: game.update_info() print('--------------------------------------------------', game.me.state) if game.me.state == 'free': cmd_list = [] cell_list = [] # 建base if game.me.gold > 80 and game.me.base_source <= 2: for cell in game.me.cells.values(): cell_list.append(cell.position) p = random.choice(cell_list) cmd_list.append(game.build(Position(p.x, p.y))) # 进攻 else: for cell in game.me.cells.values(): for pos in cell.position.get_surrounding_cardinals(): if str(game.map[pos.y][pos.x]['owner']) != str( game.me.uid): cell_list.append(pos) p = random.choice(cell_list) if game.me.gold > 5: cost = 5 else: cost = 0 cmd_list.append(game.attack(Position(p.x, p.y), cost)) game.send_cmd(cmd_list) print('attack: ', p.x, p.y)
fout.write('\n') for block_id in sorted(self.__block_pos_dict.keys()): pos = self.block_pos(block_id) fout.write('BLOCK#{} @{}\n'.format(block_id, pos)) ### @brief pos をラベル配列のインデックスに変換する. def __pos_to_index(self, pos): x = pos.x y = pos.y assert 0 <= x and x < self.width assert 0 <= y and y < self.height return y * self.__width + x ### @brief pos が範囲内かチェックする. def __check_pos(self, pos): x = pos.x y = pos.y assert 0 <= x and x < self.width assert 0 <= y and y < self.height if __name__ == '__main__': ans = Answer(5, 5) ans.set_label(Position(3, 3), 1) ans.set_block_pos(1, Position(2, 2)) ans.print()
def position(cls, pos): return Position.from_char(pos)
def _init_positions(self, tickers): for ticker in tickers: self.positions[ticker] = Position(ticker)
def _print_hands(self, deal): for position, hand in enumerate(deal.hands): print "%s: %s" % (Position.from_index(position).name, hand.pretty_one_line())