KOTH : 모든 동전에는 양면이 있습니다


26

최종 결과 제공

소개

무거운 주제 ( 판타지 전쟁 , 전 세계적으로 유행하는 ...)를 가진 나의 이전 KOTH 이후 , 나는 새로운 가벼운 마음으로 돌아 왔습니다. 이번에는 "보드 게임과 같은"상황에서 직면하고 있습니다. 거꾸로 동전 더미가 정말 큰 테이블의 중앙에 놓이고, 당신은 전리품에 대한 지분을 얻겠다고 결심합니다!

어휘

코인 : 뒤집거나 뒤집을 수없는 토큰.
Unflipped : 동전이 값이 아래를 향하도록 테이블 위에 놓입니다. 이것이 동전의 기본 상태입니다.
뒤집기 : 동전이 값을 가리키는 테이블 위에 놓입니다.
지역 : 동전 더미를 나타냅니다.
Global : 중앙의 동전 더미를 나타냅니다.

원리

게임 시작시 , 각 플레이어는 0 포인트0 코인 (플립 또는 언 플립)으로 시작합니다. 게임은 턴제입니다. 턴 중에 플레이어는 테이블 중앙에있는 동전 더미, 자신의 동전 더미 또는 다른 플레이어와 상호 작용하는 최대 3 개의 행동을 취할 수 있습니다.

플레이 순서는 게임 시작시 무작위로 정의됩니다. 인수 목록의 플레이어 순서는 턴 순서를 나타내며 해당 목록의 왼쪽에서 오른쪽으로 진행됩니다. "다음"및 "이전"은 각각 "목록의 오른쪽에있는"및 "목록의 왼쪽에있는"을 의미합니다.

게임은 50 라운드 동안 지속 되거나 플레이어 차례가 끝날 때 중앙동전0 개가 될 때까지 지속됩니다 (즉, 첫 번째 행동 후에 더미가 비어 있어도 3 가지 행동을 마치고 동전을 다시 넣을 수 있음을 의미합니다. 게임은 계속됩니다). 글로벌 코인의 시작 수는 다음 공식으로 무작위로 정의됩니다.

(2 ^ nb_players) + (nb_players * 10) - random(1 + (nb_players ^ 2))`

각 행동은 당신에게 포인트를 얻거나 (또는 ​​당신을 잃게합니다) 게임 이 끝날 때, 당신이 가진 각 동전은 당신의 포인트에 추가 될 것입니다 ( 풀리지 않은 경우 -1, 뒤집힌 경우 +2 ). 가장 높은 점수를받은 플레이어가 승리합니다.

컨트롤러는 명령 인수를 통한 입력을 제공하며 프로그램은 stdout을 통해 출력해야합니다.

통사론

입력

프로그램이 호출 될 때마다 다음 형식으로 인수를받습니다.

Round;YourPlayerId;Coins;PlayerId_Points_Flipped_Unflipped;PlayerId_Points_Flipped_Unflipped;...

라운드는 1 인덱스입니다.

입력 예

6;2;52;1_20_3_12;0_-2_0_1;2_12_1_0

여기, 당신은 그것이 6 라운드이고 당신은 2 번 선수라는 것을 알 수 있습니다. 12 포인트, 뒤집힌 동전 1 개, 뒤집지 않은 동전 0 개가 있습니다. 포인트는 음수 일 수 있습니다.

산출

공백없이 구분 기호없이 세 개의 문자를 출력해야합니다. 각 문자는 이번 차례에 한 번의 작업에 해당합니다. 문자 순서에 따라 동작 순서가 결정됩니다. 동일한 동작을 여러 번 출력 할 수 있습니다. 행동을 완료하기에 동전이 충분하지 않은 경우 사용 가능한 동전에 대해서만 사용 가능한 최대 동전 및 카운트 포인트를 사용합니다.

N: 아무 것도하지 말 것
1: 중앙 파일에서 동전 1 개 가져 오기 [효과 : 로컬 언 플립 +1 / 1 포인트 / -1 전역 unflipped]
2 : 중앙 더미에서 코인 2 개 가져 오기 [효과 : 로컬 unflipped +2 / -2 포인트 / -2 global unflipped]
3 : 중앙 더미에서 동전 3 개 가져 오기 [효과 : +3 로컬 unflipped / -3 포인트 / -3 global unflipped]
A : 더미에서 동전 1 개를 옮깁니다. [효과 : -1 로컬 unflipped / +1 포인트 / +1 global unflipped]
B : 더미에서 동전 2 개를 옮깁니다. [효과 : -2 로컬 unflipped / +2 점 / +2 global unflipped]
C : 더미에서 3 개의 동전을 옮깁니다. [효과 : -3 로컬 unflipped / +3 점 / +3 global unflipped]
X : 파일에서 동전 1 개 제거[효과 : -1 로컬 언 플립 / 0 포인트]
Y : 파일에서 동전 2 개 제거 [효과 : -2 로컬 언 플립 / 0 포인트]
Z : 파일에서 동전 3 개 제거 [효과 : -3 로컬 unflipped / 0 포인트]
R : 동전 회전 이전 플레이어에게 [효과 : 비 플립 수 신당 -1 포인트, 뒤집힌 횟수 당 +2 포인트 / 모든 플레이어에 적용]
T : 다음 플레이어로 동전 회전 [효과 : 비 플립 핑 된 수 신당 -1 포인트, 뒤집힌 수 신당 +2 포인트 / 적용 : 모든 플레이어]
F : 동전 1 개 뒤집기 [효과 : 로컬 flfl 1 개 / 로컬 뒤집기 +1 / +2 점]
U : 동전 1 개를 풉니 다 [효과 : 로컬 unflipped +1 개 / -1 로컬 뒤집기 / -2 점]

출력 예

2FF : 동전 두 개를 가져와 동전 두 개를 뒤집어 채점 -2 + 2 + 2 = 2 points

출력이 정확하지 않으면 컨트롤러는로 가정 NNN합니다.

제어 장치

컨트롤러는 GitHub 에서 찾을 수 있습니다 . 또한 Java로 작성된 두 개의 샘플 봇이 포함되어 있습니다. 실행하려면 프로젝트를 확인하고 Java IDE에서여십시오. main클래스 의 메소드의 진입 점입니다 Game. Java 8이 필요합니다.

봇을 추가하려면 먼저 컴파일 된 Java 버전 (.class 파일) 또는 해석 된 언어의 소스가 필요합니다. 프로젝트의 루트 폴더에 배치하십시오. 그런 다음 players패키지 에 새 Java 클래스를 작성하십시오 (기존 봇에서 예를 들어 볼 수 있음). 이 클래스는 Player메서드를 재정의하도록 구현해야합니다 String getCmd(). 반환 된 문자열은 봇을 실행하기위한 쉘 명령입니다. 예를 들어 다음 명령으로 Ruby 봇을 작동시킬 수 있습니다 return "C:\Ruby\bin\ruby.exe MyBot.rb";. 마지막으로 Game클래스 상단의 플레이어 배열에 봇을 추가하십시오 .

규칙

  • 봇은 다른 특정 봇을 이길 수 있도록 작성해서는 안됩니다.
  • 파일 쓰기가 허용됩니다. "yoursubmissionname.txt"에 쓰면 게임이 시작되기 전에 폴더가 비워집니다. 다른 외부 리소스는 허용되지 않습니다.
  • 제출 한 내용에 1 초의 응답 시간이 있습니다.
  • 제출물을 컴파일하고 실행하는 명령을 제공하십시오.

지원되는 언어

모든 언어를 지원하려고하지만 온라인에서 무료로 사용할 수 있어야합니다. "주류"언어를 사용하지 않는 경우 설치 지침을 제공하십시오.

현재 Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C ++ 11을 실행할 수 있습니다.

최종 결과

다음은 100 게임의 결과입니다 (포인트가 합산 됨).

1. BirdInTheHand: 1017790
2. Balance: 851428
3. SecondBest: 802316
4. Crook: 739080
5. Jim: 723440
6. Flipper: 613290
7. Wheeler: 585516
8. Oracle: 574916
9. SimpleBot: 543665
10. TraderBot: 538160
11. EgoisticalBot: 529567
12. RememberMe: 497513
13. PassiveBot: 494441
14. TheJanitor: 474069
15. GreedyRotation: 447057
16. Devil: 79212
17. Saboteur: 62240

게임의 개별 결과는 여기에 있습니다 : http://pasted.co/63f1e924 (시작 동전과 게임 당 라운드 수).

50 명성의 현상금은 우승자에게 수여된다 : 새에 손 에 의해 마틴 있음 Büttner .

참여해 주셔서 감사합니다. 다음 KOTH에 TH겠습니다 ~


1
" 효과 : -1 로컬 언 플립 / +1 로컬 플립 / +2 포인트 "가 잘못 표시됩니다. 풀리지 않은 동전의 경우 -1에서 뒤집힌 동전의 경우 +2로 이동했기 때문에 +3 포인트가 아니어야합니까?
피터 테일러

1
@PeterTaylor 포인트가 동전과 독립적이라고 생각합니다. 각 액션은 받거나 잃어버린 많은 포인트와 관련이 있으며 게임이 끝날 때 실제로 코인에 대해 얻는 포인트와 무관합니다.
마틴 엔더

"값"이 위 또는 아래를 가리키는 동전을 언급합니다. 이 값들은 무엇에 사용됩니까? 동전은 구별 가능합니까?
user2357112는 Monica

@PeterTaylor Martin Büttner가 말했듯이, 당신은 행동을 위해 동전을 얻습니다 (이 경우에는 뒤집기의 경우 +2). 그리고 마지막에 동전을 넣을 때의 포인트도 얻습니다 (이 경우에는 뒤집어 질 때마다 +2).
Thrax

ID가 0 또는 1을 기준으로합니까?
frederick

답변:


12

손에 새, 루비

def deep_copy(o)
  Marshal.load(Marshal.dump(o))
end

ID = 0
PTS = 1
FLP = 2
UFL = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

state = {
    round: round,
    id: id,
    global: global,
    players: players,
    my_pos: my_pos,
    me: players[my_pos],
    prev_p: players[my_pos-1],
    next_p: players[(my_pos+1)%nplayers],
    ends_game: round == 50 && my_pos == nplayers-1,
    score: 0
}

moves = {
    'N' => ->s{deep_copy(s)},
    '1' => ->s{t = deep_copy(s); coins = [1, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '2' => ->s{t = deep_copy(s); coins = [2, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '3' => ->s{t = deep_copy(s); coins = [3, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    'A' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'B' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'C' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'X' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Y' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Z' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'F' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t[:me][FLP] += coins; t[:score] += 2*coins; t},
    'U' => ->s{t = deep_copy(s); coins = [1, t[:me][FLP]].min; t[:me][FLP] -= coins; t[:me][UFL] += coins; t[:score] -= 2*coins; t},
    'R' => ->s{
        t = deep_copy(s)
        (-1...t[:players].size-1).each do |i|
            t[:players][i][FLP] = s[:players][i+1][FLP]
            t[:players][i][UFL] = s[:players][i+1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    },
    'T' => ->s{
        t = deep_copy(s)
        (0...t[:players].size).each do |i|
            t[:players][i][FLP] = s[:players][i-1][FLP]
            t[:players][i][UFL] = s[:players][i-1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    }
}


results = {}

'N123ABCXYZFURT'.each_char { |c1| 
    s1 = moves[c1][state]
    'N123ABCXYZFURT'.each_char { |c2| 
        s2 = moves[c2][s1]
        'N123ABCXYZFURT'.each_char { |c3| 
            s3 = moves[c3][s2]
            s3[:ends_game] ||= s3[:global] == 0
            results[c1+c2+c3] = s3
        }
    }
}

endingMoves = results.keys.select{|k| results[k][:ends_game]}

endingMoves.each{|k| results[k][:score] += 2*results[k][:me][FLP] - results[k][:me][UFL]}

$> << results.keys.shuffle.max_by {|k| results[k][:score]}

우리 중 어느 누구도 그들의 프로그램에 버그가 없다면 이것의 주요 알고리즘은 Mathias의 Oracle과 매우 유사합니다. 마지막 라운드 이전에 우리가 어떤 동전을 만들지 알 수 없다는 가정을 바탕으로, 우리는 어떤 종류의 동전을 완전히 무시하고 즉각적으로받은 포인트를 기준으로 현재 이동 세트를 평가합니다. 와. 14 3 = 2744 개의 가능한 이동 세트 만 있기 때문에 모든 점을 쉽게 시뮬레이션하여 가져올 점 수를 파악할 수 있습니다.

그러나 이동 세트가 게임을 끝내면 (전역 냄비를 0으로 줄이거 나, 50 라운드이고 우리가 마지막으로 움직일 수 있기 때문에), 마지막에 소유 한 동전을 고려 이동 세트의 값을 결정하는 이동 세트 나는 가능할 때마다 게임을 종료하는 것을 처음으로 고려했지만, 333남은 동전이 9 개 밖에 남지 않으면 끔찍한 움직임이 발생합니다.

동일한 결과를 제공하는 이동 세트가 여러 개인 경우 임의의 이동 세트를 선택합니다. (게임 종료 이동 세트에 유리하게 편향되도록 이것을 변경할 수 있습니다.)


17

오라클, Python 3

업데이트 : 회전보다 낮은 동전 더미를 선호하도록 다양한 시도의 순서가 변경되었습니다.

import sys
import itertools
from copy import deepcopy


MOVES_REQUIRED = 3

FLIPPED = 0
UNFLIPPED = 1


def filter_neighbors(neighbors, me, size):
    limit = size - MOVES_REQUIRED
    for data in neighbors:
        i, _, flipped, unflipped = map(int, data.split('_'))
        if MOVES_REQUIRED < (me - i) % size < limit:
            continue  # Skip neighbors that are too far away
        yield i, [flipped, unflipped]


class Player:
    def __init__(self, raw_data):
        _, me, coins, *data = raw_data.split(';')

        self.num_players = len(data)
        self._me = int(me)
        self._coins = int(coins)
        self._state = dict(filter_neighbors(data, self._me, self.num_players))

    def reset(self):
        self.me = self._me
        self.coins = self._coins
        self.state = deepcopy(self._state)
        self.my_state = self.state[self.me]

    def invalid_move(self, move):
        if move in 'NRT':
            return False

        if move in '123'[:self.coins]:
            return False

        flipped, unflipped = self.my_state
        if flipped and move == 'U':
            return False
        if unflipped and move == 'F':
            return False

        if move in 'AXBYCZ'[:2 * unflipped]:
            return False

        return True

    def N(self):
        return 0

    def one(self):
        self.coins -= 1
        self.my_state[UNFLIPPED] += 1
        return -1

    def two(self):
        self.coins -= 2
        self.my_state[UNFLIPPED] += 2
        return -2

    def three(self):
        self.coins -= 3
        self.my_state[UNFLIPPED] += 3
        return -3

    def A(self):
        self.coins += 1
        self.my_state[UNFLIPPED] -= 1
        return 1

    def B(self):
        self.coins += 2
        self.my_state[UNFLIPPED] -= 2
        return 2

    def C(self):
        self.coins += 3
        self.my_state[UNFLIPPED] -= 3
        return 3

    def X(self):
        self.my_state[UNFLIPPED] -= 1
        return 0

    def Y(self):
        self.my_state[UNFLIPPED] -= 2
        return 0

    def Z(self):
        self.my_state[UNFLIPPED] -= 3
        return 0

    def R(self):
        self.me = (self.me + 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def T(self):
        self.me = (self.me - 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def F(self):
        self.my_state[FLIPPED] += 1
        self.my_state[UNFLIPPED] -= 1
        return 2

    def U(self):
        self.my_state[FLIPPED] -= 1
        self.my_state[UNFLIPPED] += 1
        return -2

setattr(Player, '1', Player.one)
setattr(Player, '2', Player.two)
setattr(Player, '3', Player.three)


def scenarii(player):
    for tries in itertools.product('FUABCXYZ123NRT', repeat=MOVES_REQUIRED):
        player.reset()
        points = 0
        for try_ in tries:
            if player.invalid_move(try_):
                break
            points += getattr(player, try_)()
        else:
            yield points, ''.join(tries)


if __name__ == '__main__':
    player = Player(sys.argv[1])
    print(max(scenarii(player))[1])

가능한 모든 단일 출력을 시도하고이 턴의 최대 점수를 산출하는 출력을 유지하십시오.


아, 나는 이것을 +1 구현하려고했습니다. :) (I 여전히 수도 사실, 나는이 문제를 개선하기 위해 하나 개 또는 두 개의 작은 아이디어가 있었기 때문에 약간 .)
마틴 청산

@ MartinBüttner deepcopy관련 이웃 만 유지 하여 공간 (따라서 [ ]) 복잡성 을 개선 할 생각을했습니다 . 그것이 어떻게 영향을 줄지 잘 모르겠습니다.
409_Conflict

@Thrax 나는 버그를 filter_neighbors수정 invalid_move하고 문제의 설명을 설명하기 위해 수정했습니다. 그래도 오류를 재현 할 수 없습니다 : $ python oracle.py '4;7;2040;8_-28_1_10;9_-43_0_9;2_-10_4_3;6_-24_6_3;0_6_2_12;1_48_3_0;10_21_4_8;5_6_5_1;4_-12_3_7;7_10_1_3;3_1_1_0'printsTTR
409_Conflict

7

탐욕스러운 회전, 루비

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

prev_p = players[my_pos-1]
next_p = players[(my_pos+1)%nplayers]

prev_score = 2*prev_p[2] - prev_p[3]
next_score = 2*next_p[2] - next_p[3]

take_from = prev_p

$><< '3'
if prev_score > next_score || prev_score == next_score && prev_p[3] > next_p[3]
    $><< 'T'
else
    $><< 'R'
    take_from = next_p
end

if take_from[3] >= 3
    $><< 'C'
elsif take_from[3] >= 1
    $><< 'F'
else
    $><< 'N'
end

이것은 ArtOfCode의 접근 방식과 매우 유사합니다.이 점은 어떤 이웃에서 더 많은 포인트를 얻을 수 있는지 확인 하고 회전 후 3 개 이상의 코인으로 끝나는 C대신 선택 합니다 F.

이 글을 작성한 후에는 가능한 한 복용하여 회전 전에 매번 모든 동작 중에서 최선을 선택하는 것이 더 나은 접근 방법이라고 확신합니다. 고정 된 "플립 핑 해제, 회전, 제거하기" 플 리핑되지 않은 "패턴).

이것은 또한 실제로 소유 한 동전으로 표현되는 암시 적 포인트를 고려하지 않습니다 (게임이 어쨌든 내 동전을 유지하지 못할 정도로 충분히 라운드를 지속 할 것이라는 가정에 근거 함).


@MegaTom Whoops, 그것을 잡아 주셔서 감사합니다.
마틴 엔더

6

플리퍼, 파이썬 2

플리퍼는 동전을 모아 뒤집지 않은 채 뒤집기를 시도합니다. 플리퍼는 똑똑한 선수는 아니지만 게임에서 긍정적 인 힘이 되려고 노력합니다.

import sys, random

# process input data (not used here):
args = sys.argv[1].split(';')
rounds, myid, coins = map(int, args[:3])
players = [map(int, data.split('_')) for data in args[3:]]

# implement strategy using multiples of 'N123ABCXYZRTFU':
options = '12333FFFFFFFFFFF'
print ''.join(random.choice(options) for i in range(3))

플리퍼는 python flipper.py <arg>뛰기 만하면됩니다 .


5

SimpleBot, Python 3

SimpleBot은 간단합니다. 그는 한 가지 전략을 세웠으며 그 전략을 고수 할 것입니다.

실행하려면

python3 main.py

main.py파일 내용 은 다음과 같습니다.

def main():
    print("3RF")


if __name__ == "__main__":
    main()

5

밸런스, 루아

저울은 토큰에 잔액을 유지하려고 노력하여 누군가가 그에 대해 행동 R하고 T행동 할 경우의 손실을 최소화합니다 . 그는이 생활 방식이 진실한 것이라고 생각하고 뒤집어 놓거나 뒤집지 않은 동전의 균형을 잘 유지하지 못하는 사람에게는 시행해야하므로 자신과 가까운 사람은 점수를 잃을 수있는 즉시 처벌을받습니다.

실행하려면 다음 명령이 필요합니다.

lua balance.lua

파일 balance.lua에 다음 코드가 포함되어있는 경우 :

local datas={}
local arg=arg[1]..";"

-- parse the arguments
-- add some meta datas for debuging purpose/usefulness
arg:gsub("(.-);",function(c)
  if not datas.round
  then
    datas.round=c+0
  elseif not datas.myID
  then
    datas.myID=c+0
  elseif not datas.coins
  then
    datas.coins=c+0
  else
    datas[#datas+1]={}
    datas[#datas].repr=c
    c=c.."_"
    tmp={}
    c:gsub("(.-)_",function(d) tmp[#tmp+1]=d end)
    datas[#datas].id=tmp[1]+0
    datas[#datas].points=tmp[2]+0
    datas[#datas].flip=tmp[3]+0
    datas[#datas].unflip=tmp[4]+0
    if datas[#datas].id==datas.myID
    then
      datas.myOrder=#datas
      datas.myDatas=datas[#datas]
    end
  end
end)

local actions=""
-- construct actions
for i=1,3
do
  -- if we aren't in balance and can grab more coins
  -- we do it
  if #actions==0 and datas.myDatas.unflip<=datas.myDatas.flip/2 and datas.coins>=3
  then
    actions=actions.."3"
    datas.myDatas.unflip=datas.myDatas.unflip+3
    datas.coins=datas.coins-3
  -- if we couldn't grab coins, but aren't in balance, we flip some coins
  elseif datas.myDatas.unflip>datas.myDatas.flip/2
  then
    actions=actions.."F"
    datas.myDatas.unflip=datas.myDatas.unflip-1
    datas.myDatas.flip=datas.myDatas.flip+1

  -- if we didn't have anything to do on our pile, let's punish
  -- the fools who doesn't follow the great Balance principle
  else
    previous=datas.myOrder<2 and #datas or datas.myOrder-1
    following=datas.myOrder>=#datas and 1 or datas.myOrder+1

    lossPrev=-datas[previous].flip + 2*datas[previous].unflip
    lossFoll=-datas[following].flip+ 2*datas[following].unflip
    if lossFoll>0 and lossPrev>0
    then
      actions =actions.."N"
    elseif lossFoll>=lossPrev
    then
      actions=actions.."T"
      datas[following].unflip,datas[following].flip=datas[following].flip,datas[following].unflip
    else
      actions=actions.."R"
      datas[previous].unflip,datas[previous].flip=datas[previous].flip,datas[previous].unflip
    end
  end
end
print(actions)

@Thrax 감사합니다. 이 줄에 대해 1- 인덱스 값으로 작업하는 것을 잊었습니다.
Katenkyo

4

관리인, 파이썬 3

그는 다른 플레이어들이이 동전으로 엉망을 청소하고 풀에 다시 넣습니다.

import sys;
def Parse(S):
    T = S.split(';');
    me = eval(T[1]);
    N = len(T)-3;
    A = list(map(lambda x: list(map(lambda y:int(y),T[3+((2*N+x+me)%N)].split('_'))),range(-3,4)));    
    Dic = {}
    for a in A:
        Dic[a[0]] = a[1:];
    Dic[-1] = [me];
    return Dic;
def Recursive(Dic,me,D):
    if D==3: return '';
    V = Dic[me];
    N = max(Dic.keys());
    Next = (me+1)%N;
    Prev = (N+1+me)%N;
    for i in range(3,0,-1):
        if V[2]>=i:
            Dic[me][2] = Dic[me][2]-i;
            return chr((i-1)+ord('A'))+Recursive(Dic,me,D+1);
    if V[1]>0:
        Dic[me][1] = Dic[me][1]-1;
        Dic[me][2] = Dic[me][2]+1;
        return 'U'+Recursive(Dic,me,D+1);
    if Dic[Next][2]>Dic[Prev][2]:
        return 'T'+Recursive(Dic,Next,D+1);
    return 'R'+Recursive(Dic,Prev,D+1);
Dic = Parse(sys.argv[1]);
me = Dic[-1][0];
print(Recursive(Dic,me,0));

그는 뒤집어 놓지 않은 동전을 모두 돌려 주려고 노력하고, 뒤집힌 동전이 붙어 있으면 뒤집을 것이고, 모든 동전을 제거하면 다른 사람을 얻게됩니다.


3

사기꾼, R

args <- strsplit(commandArgs(TRUE),";")[[1]]
state <- as.data.frame(do.call(rbind,strsplit(args[-(1:3)],"_")), stringsAsFactors=FALSE)
colnames(state) <- c("id","pts","flipped","unflipped")
state$flipped <- as.integer(state$flipped)
state$unflipped <- as.integer(state$unflipped)
nb <- nrow(state)
score <- function(place) 2*state$flipped[place]-state$unflipped[place]
my_place <- which(state$id==args[2])
next_1 <- ifelse(my_place!=nb,my_place+1,1)
next_2 <- ifelse(next_1!=nb,next_1+1,1)
next_3 <- ifelse(next_2!=nb,next_2+1,1)
previous_1 <- ifelse(my_place!=1,my_place-1,nb)
previous_2 <- ifelse(previous_1!=1,previous_1-1,nb)
previous_3 <- ifelse(previous_2!=1,previous_2-1,nb)
n <- 3
out <- c()
while(n){
    M <- N <- score(my_place)
    R <- switch(n,"1"=score(next_1),
                "2"=cumsum(c(score(next_1),score(next_2))),
                "3"=cumsum(c(score(next_1),score(next_2),score(next_3))))
    P <- switch(n,"1"=score(previous_1),
                "2"=cumsum(c(score(previous_1),score(previous_2))),
                "3"=cumsum(c(score(previous_1),score(previous_2),score(previous_3))))
    M <- c(M,M+R[-n])
    N <- c(N,N+P[-n])
    if(any(R>M & R>0)){
        action <- c("R","RR","RRR")[which.max(R-M)]
        out <- c(out, action)
        state[,3:4] <- state[c((nchar(action)+1):nb,seq_len(nchar(action))),3:4]
        n <- n-nchar(action)
    }else if(any(P>N & P>0)){
        action <- c("T","TT","TTT")[which.max(P-N)]
        out <- c(out, action)
        state[,3:4] <- state[c((nb+1-seq_len(nchar(action))),1:(nb-seq_len(nchar(action)))),3:4]
        n <- n-nchar(action)
    }else if(n>1 & all(R[1]+M[1]>c(0,P[1]+M[1],R[1]+R[2]))){
        out <- c(out,"RT")
        n <- n-2
    }else if(n>1 & all(P[1]+M[1]>c(0,R[1]+M[1],P[1]+P[2]))){
        out <- c(out,"TR")
        n <- n-2
    }else{
        out <- c(out, switch(n,"1"="A","2"="1F","3"="2FF"))
        n <- 0
        }
    }
cat(paste(out,collapse=""))

실행하려면 Rscript Crook.R

기본적으로 교환이 유리하지 않은 경우에만 동전을 이웃과 교환합니다. 유리한 교환이 가능하지 않으면 비율을 그대로 유지하면서 일부 포인트를 생성하는 방식으로 글로벌 파일과 동전을 교환합니다.

편집 : 나는 다음 봇 대신 다음과 이전 2 및 3 플레이어 스택을 확인하고 전반적으로 여러 번 회전시키는 것이 유리한지 확인 하여이 봇에 약간의 깊이를 추가했습니다.

두 번째 편집 : @ MartinBüttner의 아이디어에 따라 봇은 이제 이웃보다 더 유익한 경우 "RT"또는 "TR"을 수행합니다 (구현하지 않을 경우 :)).


편집을 다시하십시오 : 당신 옆에있는 사람이 뒤집힌 동전이 많으면 RTR그의 동전에서 두 번 점수를 얻도록하는 것이 가장 좋습니다 .
마틴 엔더

참된. 그것은 또한 한 번의 점수를 얻은 이웃 중 하나를 줄 것입니다. 그러나 나는 그것에 대해 실제로 생각할 것입니다, 그것은 탐구하는 아이디어입니다.
plannapus

@ MartinBüttner Ok 결국 나는 로봇의 정신을 유지하면서 그것을 구현하는 방법을 발견했습니다. 제안 해 주셔서 감사합니다!
plannapus

@thrax 다음 게임을 실행할 때 내 봇을 업데이트하는 것을 잊지 않도록 github 저장소의 내 봇 버전이 오래된 버전임을 경고해야한다고 생각했습니다.
plannapus

3

짐, 루비

Martin Büttner의 Greedy Rotation을 기반으로 합니다.

PlayerId = 0
Points = 1
Flipped = 2
Unflipped = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

if(round == 1)
    print '3FF'
    exit
end

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |a| a[PlayerId] == id }

coin_vals = players.map{|a| a[Flipped]*2 - a[Unflipped]}

move = [-1,1].max_by{|s|
    swap_gain = coin_vals.rotate(s)
    scores = (0...nplayers).map{|i|
        swap_gain[i]+players[i][Points]
    }
    scores.delete_at(my_pos)-scores.max
}
if move == 1
    print 'R'
else
    print 'T'
end

print ['1F', 'FF'][rand 2]

그에게 최고의 선수와 비교하여 가장 많은 점수를주는 것에 따라 한 방향 또는 다른 방향으로 회전합니다. 그런 다음 그는 빠른 현금을 요구합니다.


2

트레이더 봇

이 봇은 해당 액션에서 가장 많은 포인트를 차지할 때마다 회전을 시도합니다. 회전 할 수없는 경우 다음과 같은 조치로 고정되지 않은 코인을 제거하거나 몇 가지 더 변경하십시오.

import java.util.ArrayList;

import java.util.List;

공개 클래스 TraderBot {

class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }


}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new TraderBot().play(s);
}

private void play(String[] s){
    parse(s[0]);
    System.out.println(action() + action() + action());
}

private int simRotateNext(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = 0; i < players.size(); i++){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(next).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(next).getId() == myself.getId()){
            myP = p;
        }

    }
    return  myP - maxP;
}

private int simRotatePrev(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = players.size() -1; i > 0; i--){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(prev).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(prev).getId() == myself.getId()){
            myP = p;
        }
    }
    return  myP - maxP;
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int next = simRotateNext();
    int prev = simRotatePrev();

    if (next > 0 || prev > 0){
        if (next > prev){
            rotateNext();
            return "T";
        } else {
            rotatePrev();
            return "R";
        }
    }

    if (myself.getUnflip() > 3){
        myself.unflip -= 3;
        myself.points += 3;
        return "C";
    }

    if (myself.getUnflip() > 0){
        myself.unflip -= 1;
        myself.points += 2;
        return "F";
    }

    if (myself.getPoints() > otherMaxPoints){
        return "N";
    } else {
        myself.unflip += 3;
        myself.points -= 3;
        return "3";
    }

}

private void parse(String s){
    String[] ps = s.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}
}

실행하려면 : 기본 봇과 동일한 폴더에 추가 한 후 다음 클래스를 만듭니다.

package players;

import controller.Player;

public class TraderBot extends Player {

    @Override
    public String getCmd() {
        return "java TraderBot";
    }   
}

그런 다음 해당 클래스를 Player[] players배열에 추가하십시오 .


2

조타실

휠러는 동전을 회전시킬 때 가장 좋은 움직임을 계산했습니다.

import java.util.ArrayList;
import java.util.List;

public class Wheeler {

String[] actions = {"TTT", "TTR", "TRR", "TRT", "RRR", "RRT", "RTR", "RTT"};
String paramString;

class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }
    @Override
    public String toString() {
        return "Player [id=" + id + ", points=" + points + ", flip=" + flip + ", unflip=" + unflip + "]";
    }




}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new Wheeler().play(s);
}

private void play(String[] s){
    paramString = s[0];
    reset();
    System.out.println(action());
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int maxPoints = myself.getPoints();
    String action = "1F2";
    for (String s : actions){
        int cPoints = 0;
        for (char c : s.toCharArray()){
            if (c == 'T'){
                cPoints += rotateNext();
            } else {
                cPoints += rotatePrev();
            }
        }
        if (cPoints > maxPoints){
            action = s;
        }
        reset();
    }
    return action;      
}


private void reset(){
    players = new ArrayList<>();
    String[] ps = paramString.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}

}

2

파괴자, 파이썬 2

import random
moves = '3R'
print '33' + ''.join(random.choice(moves))

무작위성은 아마도 방해가되지 않을 것이라는 것을 의미하지만, 나중에 나는 '끝'(얼마나 많은 턴 / 코인이 남았는지)까지 기다릴 것이고, 그 다음에 접근 할 수있는 가까운 플레이어를 훔쳐보고 ... 다른 사람도 회전을 사용할 가능성을 고려할 때 실제로 한 번만 회전하는 것은 실제로 좋지 않은 것 같습니다. 나는 이것이 잘 작동한다고 생각하지 않습니다 ...


이것 하나가 가장하는 것은 동전을 쌓아내는 것입니다. 자신과 다른 사람들에게 많은 부정적인 점을 줄뿐 아니라
MegaTom

@ MegaTom 그래, 그게 부작용이 될 것이라고 생각했는데, 내가 생각하는 총 동전에 대한 공식에 유리합니다. 난수로 만들 수 있습니다. 그리고 부정적인 점에서 다른 사람에게 부정적인 점을주는 것은 또 다른 방법입니다!
Neal

sys 가져 오기가 필요하지 않습니다. : P
고양이

2

둘째, 파이썬 3

이 프로그램은 가능한 모든 3 가지 이동 조합을 거치며 두 번째로 가장 좋은 조합을 선택합니다.

당신이 완벽한 움직임을 가졌다면 아마도 함정일 것입니다.

편집 : 주석 처리 된 입력 제거

import sys
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
C=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False#stupid check
    if P:#legality check
        z=0
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:z-=3;self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:z-=2;self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:z-=1;self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:z+=1;self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:z+=2;self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:z+=3;self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:z+=2;self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:z-=2;self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
    if P:
        C.append(z);B.append((z,y))
c=list(set(C))
c.sort()
c=c[::-1][1];D=[]
for x in B:
    if c in x:D.append(x)
print(D[randint(0,len(D)-1)][1])

편집 : 코드가 임의의 법적 이동을 인쇄했습니다. 이제 두 번째 최상의 결과를 반환해야합니다.


1

악마의 봇

결과는 악마 수의 절반에 불과하지만 결과는 상당히 비참해야합니다. 한 번에 9 개의 동전을 가져 가면 결국 동전 더미가 소모됩니다. 이 봇은 동전을 절대로 뒤집지 않기 때문에 회전이있을 때 옆에 앉아있는 사람에게는 매우 나쁘다 (이 봇이 한 턴마다 9 점씩).

print("333")

명령: python3 devil.py

나중에 진짜 봇을 만들려고합니다.


트윗 담아 가기 나는 그 것을 눈치 채지 못했습니다. 말해 주셔서 감사합니다!
frederick

1

나를 기억해, 파이썬 3

이 프로그램에는 고정 된 SecondBest 봇에 대한 테스트에서 상당량의 내장 데이터가 포함되어 있습니다.

그것은 해야 이동 사용하는 것이 가장 좋은 무엇인지에 대해 배울 수 있지만, 다른 플레이어의 입력을 사용하지 않습니다.

편집 : 불필요한 포인트 계산 제거

편집 : 주석 처리되지 않은 플레이어 입력

import sys
file=sys.argv[0].split('\\')[::-1][0]
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False
    if P:
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
    if P:
        B.append(y)
Pos=list(B)
B=[]
#
C=[['NNN',0],['NN1',-1],['NN2',-2],['NN3',-3],['NNR',-6],['NNT',-1],['N1N',-1],['N11',-2],['N12',-3],['N13',-4],['N1X',-1],['N1R',-7],['N1T',-2],['N1F',1],['N1U',-3],['N2N',-2],['N21',-3],['N22',-4],['N23',-5],['N2A',-1],['N2X',-2],['N2Y',-2],['N2R',-8],['N2T',-3],['N2F',0],['N2U',-4],['N3N',-3],['N31',-4],['N32',-5],['N33',-6],['N3A',-2],['N3B',-1],['N3X',-3],['N3Y',-3],['N3Z',-3],['N3R',-9],['N3T',-4],['N3F',-1],['N3U',-5],['NRN',-6],['NR1',-7],['NR2',-8],['NR3',-9],['NRA',-5],['NRB',-4],['NRC',-3],['NRX',-6],['NRY',-6],['NRZ',-6],['NRR',-12],['NRT',-7],['NRF',-4],['NRU',-8],['NTN',-1],['NT1',-2],['NT2',-3],['NT3',-4],['NTA',0],['NTX',-1],['NTR',-7],['NTT',-2],['NTF',1],['NTU',-3],['1NN',-1],['1N1',-2],['1N2',-3],['1N3',-4],['1NA',0],['1NX',-1],['1NR',-7],['1NT',-2],['1NF',1],['1NU',-3],['11N',-2],['111',-3],['112',-4],['113',-5],['11B',0],['11X',-2],['11Y',-2],['11R',-8],['11T',-3],['11F',0],['11U',-4],['12N',-3],['121',-4],['122',-5],['123',-6],['12A',-2],['12C',0],['12X',-3],['12Y',-3],['12Z',-3],['12R',-9],['12T',-4],['12F',-1],['12U',-5],['13N',-4],['131',-5],['132',-6],['133',-7],['13A',-3],['13B',-2],['13X',-4],['13Y',-4],['13Z',-4],['13R',-10],['13T',-5],['13F',-2],['13U',-6],['1XN',-1],['1X1',-2],['1X2',-3],['1X3',-4],['1XR',-7],['1XT',-2],['1RN',-7],['1R1',-8],['1R2',-9],['1R3',-10],['1RA',-6],['1RB',-5],['1RC',-4],['1RX',-7],['1RY',-7],['1RZ',-7],['1RR',-13],['1RT',-8],['1RF',-5],['1RU',-9],['1TN',-2],['1T1',-3],['1T2',-4],['1T3',-5],['1TA',-1],['1TX',-2],['1TR',-8],['1TT',-3],['1TF',0],['1TU',-4],['1FN',1],['1F1',0],['1F2',-1],['1F3',-2],['1FR',-5],['1FT',0],['1UN',-3],['1U1',-4],['1U2',-5],['1U3',-6],['1UA',-2],['1UB',-1],['1UX',-3],['1UY',-3],['1UR',-9],['1UT',-4],['1UU',-5],['2NN',-2],['2N1',-3],['2N2',-4],['2N3',-5],['2NA',-1],['2NB',0],['2NX',-2],['2NY',-2],['2NR',-8],['2NT',-3],['2NF',0],['2NU',-4],['21N',-3],['211',-4],['212',-5],['213',-6],['21B',-1],['21C',0],['21X',-3],['21Y',-3],['21Z',-3],['21R',-9],['21T',-4],['21F',-1],['21U',-5],['22N',-4],['221',-5],['222',-6],['223',-7],['22A',-3],['22C',-1],['22X',-4],['22Y',-4],['22Z',-4],['22R',-10],['22T',-5],['22F',-2],['22U',-6],['23N',-5],['231',-6],['232',-7],['233',-8],['23A',-4],['23B',-3],['23X',-5],['23Y',-5],['23Z',-5],['23R',-11],['23T',-6],['23F',-3],['23U',-7],['2AN',-1],['2A2',-3],['2A3',-4],['2AR',-7],['2AT',-2],['2XN',-2],['2X1',-3],['2X2',-4],['2X3',-5],['2XA',-1],['2XX',-2],['2XR',-8],['2XT',-3],['2XF',0],['2XU',-4],['2YN',-2],['2Y1',-3],['2Y2',-4],['2Y3',-5],['2YR',-8],['2YT',-3],['2RN',-8],['2R1',-9],['2R2',-10],['2R3',-11],['2RA',-7],['2RB',-6],['2RC',-5],['2RX',-8],['2RY',-8],['2RZ',-8],['2RR',-14],['2RT',-9],['2RF',-6],['2RU',-10],['2TN',-3],['2T1',-4],['2T2',-5],['2T3',-6],['2TA',-2],['2TX',-3],['2TR',-9],['2TT',-4],['2TF',-1],['2TU',-5],['2FN',0],['2F1',-1],['2F2',-2],['2F3',-3],['2FA',1],['2FX',0],['2FR',-6],['2FT',-1],['2FF',2],['2UN',-4],['2U1',-5],['2U2',-6],['2U3',-7],['2UA',-3],['2UB',-2],['2UC',-1],['2UX',-4],['2UY',-4],['2UZ',-4],['2UR',-10],['2UT',-5],['2UU',-6],['3NN',-3],['3N1',-4],['3N2',-5],['3N3',-6],['3NA',-2],['3NB',-1],['3NC',0],['3NX',-3],['3NY',-3],['3NZ',-3],['3NR',-9],['3NT',-4],['3NF',-1],['3NU',-5],['31N',-4],['311',-5],['312',-6],['313',-7],['31B',-2],['31C',-1],['31X',-4],['31Y',-4],['31Z',-4],['31R',-10],['31T',-5],['31F',-2],['31U',-6],['32N',-5],['321',-6],['322',-7],['323',-8],['32A',-4],['32C',-2],['32X',-5],['32Y',-5],['32Z',-5],['32R',-11],['32T',-6],['32F',-3],['32U',-7],['33N',-6],['331',-7],['332',-8],['333',-9],['33A',-5],['33B',-4],['33X',-6],['33Y',-6],['33Z',-6],['33R',-12],['33T',-7],['33F',-4],['33U',-8],['3AN',-2],['3A2',-4],['3A3',-5],['3AR',-8],['3AT',-3],['3BN',-1],['3B1',-2],['3B3',-4],['3BA',0],['3BX',-1],['3BR',-7],['3BT',-2],['3BF',1],['3BU',-3],['3XN',-3],['3X1',-4],['3X2',-5],['3X3',-6],['3XA',-2],['3XB',-1],['3XX',-3],['3XY',-3],['3XR',-9],['3XT',-4],['3XF',-1],['3XU',-5],['3YN',-3],['3Y1',-4],['3Y2',-5],['3Y3',-6],['3YA',-2],['3YX',-3],['3YR',-9],['3YT',-4],['3YF',-1],['3YU',-5],['3ZN',-3],['3Z1',-4],['3Z2',-5],['3Z3',-6],['3ZR',-9],['3ZT',-4],['3RN',-9],['3R1',-10],['3R2',-11],['3R3',-12],['3RA',-8],['3RB',-7],['3RC',-6],['3RX',-9],['3RY',-9],['3RZ',-9],['3RR',-15],['3RT',-10],['3RF',-7],['3RU',-11],['3TN',-4],['3T1',-5],['3T2',-6],['3T3',-7],['3TA',-3],['3TX',-4],['3TR',-10],['3TT',-5],['3TF',-2],['3TU',-6],['3FN',-1],['3F1',-2],['3F2',-3],['3F3',-4],['3FA',0],['3FB',1],['3FX',-1],['3FY',-1],['3FR',-7],['3FT',-2],['3FF',1],['3UN',-5],['3U1',-6],['3U2',-7],['3U3',-8],['3UA',-4],['3UB',-3],['3UC',-2],['3UX',-5],['3UY',-5],['3UZ',-5],['3UR',-11],['3UT',-6],['3UU',-7],['RNN',-6],['RN1',-7],['RN2',-8],['RN3',-9],['RNA',-5],['RNB',-4],['RNC',-3],['RNX',-6],['RNY',-6],['RNZ',-6],['RNR',-12],['RNT',-7],['RNF',-4],['RNU',-8],['R1N',-7],['R11',-8],['R12',-9],['R13',-10],['R1B',-5],['R1C',-4],['R1X',-7],['R1Y',-7],['R1Z',-7],['R1R',-13],['R1T',-8],['R1F',-5],['R1U',-9],['R2N',-8],['R21',-9],['R22',-10],['R23',-11],['R2A',-7],['R2C',-5],['R2X',-8],['R2Y',-8],['R2Z',-8],['R2R',-14],['R2T',-9],['R2F',-6],['R2U',-10],['R3N',-9],['R31',-10],['R32',-11],['R33',-12],['R3A',-8],['R3B',-7],['R3X',-9],['R3Y',-9],['R3Z',-9],['R3R',-15],['R3T',-10],['R3F',-7],['R3U',-11],['RAN',-5],['RA2',-7],['RA3',-8],['RAA',-4],['RAB',-3],['RAC',-2],['RAX',-5],['RAY',-5],['RAZ',-5],['RAR',-11],['RAT',-6],['RAF',-3],['RAU',-7],['RBN',-4],['RB1',-5],['RB3',-7],['RBA',-3],['RBB',-2],['RBC',-1],['RBX',-4],['RBY',-4],['RBZ',-4],['RBR',-10],['RBT',-5],['RBF',-2],['RBU',-6],['RCN',-3],['RC1',-4],['RC2',-5],['RCA',-2],['RCB',-1],['RCC',0],['RCX',-3],['RCY',-3],['RCZ',-3],['RCR',-9],['RCT',-4],['RCF',-1],['RCU',-5],['RXN',-6],['RX1',-7],['RX2',-8],['RX3',-9],['RXA',-5],['RXB',-4],['RXC',-3],['RXX',-6],['RXY',-6],['RXZ',-6],['RXR',-12],['RXT',-7],['RXF',-4],['RXU',-8],['RYN',-6],['RY1',-7],['RY2',-8],['RY3',-9],['RYA',-5],['RYB',-4],['RYC',-3],['RYX',-6],['RYY',-6],['RYZ',-6],['RYR',-12],['RYT',-7],['RYF',-4],['RYU',-8],['RZN',-6],['RZ1',-7],['RZ2',-8],['RZ3',-9],['RZA',-5],['RZB',-4],['RZC',-3],['RZX',-6],['RZY',-6],['RZZ',-6],['RZR',-12],['RZT',-7],['RZF',-4],['RZU',-8],['RRN',-12],['RR1',-13],['RR2',-14],['RR3',-15],['RRA',-11],['RRB',-10],['RRC',-9],['RRX',-12],['RRY',-12],['RRZ',-12],['RRR',-18],['RRT',-13],['RRF',-10],['RRU',-14],['RTN',-7],['RT1',-8],['RT2',-9],['RT3',-10],['RTA',-6],['RTX',-7],['RTR',-13],['RTT',-8],['RTF',-5],['RTU',-9],['RFN',-4],['RF1',-5],['RF2',-6],['RF3',-7],['RFA',-3],['RFB',-2],['RFC',-1],['RFX',-4],['RFY',-4],['RFZ',-4],['RFR',-10],['RFT',-5],['RFF',-2],['RUN',-8],['RU1',-9],['RU2',-10],['RU3',-11],['RUA',-7],['RUB',-6],['RUC',-5],['RUX',-8],['RUY',-8],['RUZ',-8],['RUR',-14],['RUT',-9],['RUU',-10],['TNN',-1],['TN1',-2],['TN2',-3],['TN3',-4],['TNA',0],['TNX',-1],['TNR',-7],['TNT',-2],['TNF',1],['TNU',-3],['T1N',-2],['T11',-3],['T12',-4],['T13',-5],['T1B',0],['T1X',-2],['T1Y',-2],['T1R',-8],['T1T',-3],['T1F',0],['T1U',-4],['T2N',-3],['T21',-4],['T22',-5],['T23',-6],['T2A',-2],['T2C',0],['T2X',-3],['T2Y',-3],['T2Z',-3],['T2R',-9],['T2T',-4],['T2F',-1],['T2U',-5],['T3N',-4],['T31',-5],['T32',-6],['T33',-7],['T3A',-3],['T3B',-2],['T3X',-4],['T3Y',-4],['T3Z',-4],['T3R',-10],['T3T',-5],['T3F',-2],['T3U',-6],['TAN',0],['TA2',-2],['TA3',-3],['TAR',-6],['TAT',-1],['TXN',-1],['TX1',-2],['TX2',-3],['TX3',-4],['TXR',-7],['TXT',-2],['TRN',-7],['TR1',-8],['TR2',-9],['TR3',-10],['TRA',-6],['TRB',-5],['TRC',-4],['TRX',-7],['TRY',-7],['TRZ',-7],['TRR',-13],['TRT',-8],['TRF',-5],['TRU',-9],['TTN',-2],['TT1',-3],['TT2',-4],['TT3',-5],['TTA',-1],['TTX',-2],['TTR',-8],['TTT',-3],['TTF',0],['TTU',-4],['TFN',1],['TF1',0],['TF2',-1],['TF3',-2],['TFR',-5],['TFT',0],['TUN',-3],['TU1',-4],['TU2',-5],['TU3',-6],['TUA',-2],['TUB',-1],['TUX',-3],['TUY',-3],['TUR',-9],['TUT',-4],['TUU',-5]]
#
points=0
#
dpoints=self[1]-points
z=0
for x in range(len(Pos)):
    y=Pos[x]
    z=0
    for x in C:
     if x[0]==y:z=x[1]
    B.append((z,y))
B.sort()
B=B[::-1]
G=open(file,'r')
H=G.read().split('#')[::-1]
G.close()
G=open(file,'w')
H[3]=H[3].replace(H[3][8:-1],str(self[1]))
J=eval(H[4][3:-1])
A=[B[0][1],dpoints]
P=1
for x in range(0,len(J)):
 if J[x][0]==A[0]:J[x][1]+=A[1];P=0
if P:J.append(A)
H[4]='\nC='+str(J)+'\n'
s=''
for x in H[::-1]:s+=x;s+='#'
G.write(s[:-1])
G.close()
print(B[0][1])

5 번 라인에 입력 한 내용이 있다고 생각합니다.
Averroes

지금 수정해야합니다. 지적 해 주셔서 감사합니다.
마젠타
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.