[Question]
  [
**Final results available**
# Introduction
After my previous KOTH with heavy themes ([fantasy war](https://codegolf.stackexchange.com/questions/44978/koth-warring-towns), [worldwide pandemic](https://codegolf.stackexchange.com/questions/70135/koth-a-world-wide-pandemic)...), I'm back with a new lighthearted game. This time, you are facing off in a "board game-like" situation. A pile of upside down coins is placed at the center of a really big table, and you are determined to get your share of the loot!
# Glossary
> 
> *Coins*: Tokens that can either be flipped or unflipped.  
> 
> *Unflipped*: Coins placed on the table with their value pointing down. This is the default state of the coins.  
> 
> *Flipped*: Coins placed on the table with their value pointing up.  
> 
> *Local*: Refers to your pile of coins.  
> 
> *Global*: Refers to the pile of coins at the center. 
> 
> 
> 
# Principle
**At the start** of the game, each player starts with **0 points** and **0 coins** (flipped or unflipped). The game is turn-based. During their turn, players can take up to 3 actions interacting either with the pile of coins at the center of the table, their own pile of coins or with other players. 
Play order is defined randomly at the start of the game. The order of the players in the argument list represents the turn order, and it goes from left to right in that list. "Next" and "Previous" refer respectively to "on the right in that list" and "on the left in that list" with a loop if you're the last of either side.
The game lasts for **50 rounds** or until there are **0 coins at the center** at the end of a player turn (meaning that you will finish your 3 actions even if the pile is empty after your first action, and you can put back coins to let the game continue). The starting number of global coins is defined randomly with this formula: 
```
(2 ^ nb_players) + (nb_players * 10) - random(1 + (nb_players ^ 2))`
```
Each action will get you points (or make you lose some) and **at the end** of the game, **each coin** you have will be added to your points (**-1 for unflipped, +2 for flipped**). The player with the highest score wins.
The controller provides you with input via command arguments, and your program has to output via stdout.
# Syntax
**Input**
Each time your program is called, it will receive arguments in this format:
`Round;YourPlayerId;Coins;PlayerId_Points_Flipped_Unflipped;PlayerId_Points_Flipped_Unflipped;...`
Rounds are 1-indexed.
**Example input**
`6;2;52;1_20_3_12;0_-2_0_1;2_12_1_0`
Here, you see it is the 6th round and you are player 2. There are 52 coins in the central pile. You have 12 points, 1 flipped coin and 0 unflipped coin. Points can be negative.
**Output**
You have to output three characters (no space, no separator), which each correspond to one action you'll take this turn. The order of the characters determine the order of the actions. You can output the same actions multiple times. In case there is not enough coins to complete your action, it will use the maximum of available coins and count points only for the coins used.
`N`: Do Nothing  
`1`: Take 1 coin from the central pile *[Effects: +1 local unflipped / -1 point / -1 global unflipped]*  
`2`: Take 2 coins from the central pile *[Effects: +2 local unflipped / -2 points / -2 global unflipped]*  
`3`: Take 3 coins from the central pile *[Effects: +3 local unflipped / -3 points / -3 global unflipped]*  
`A`: Put back 1 coin from your pile *[Effects: -1 local unflipped / +1 point / +1 global unflipped]*  
`B`: Put back 2 coins from your pile *[Effects: -2 local unflipped / +2 points / +2 global unflipped]*  
`C`: Put back 3 coins from your pile *[Effects: -3 local unflipped / +3 points / +3 global unflipped]*  
`X`: Remove 1 coin from your pile *[Effects: -1 local unflipped / 0 point]*  
`Y`: Remove 2 coins from your pile *[Effects: -2 local unflipped / 0 point]*  
`Z`: Remove 3 coins from your pile *[Effects: -3 local unflipped / 0 point]*  
`R`: Rotate coins to previous player *[Effects: -1 point per unflipped received, +2 points per flipped received / applies to all players]*  
`T`: Rotate coins to next player *[Effects: -1 point per unflipped received, +2 points per flipped received / applies to all players]*  
`F`: Flip 1 coin *[Effects: -1 local unflipped / +1 local flipped / +2 point]*  
`U`: Unflip 1 coin *[Effects: +1 local unflipped / -1 local flipped / -2 point]* 
**Example output**
`2FF` : Takes two coins and flips two coin, scoring `-2 + 2 + 2 = 2 points`
If your output is incorrect, controller will assume `NNN`.
# Controller
You can find the controller on [GitHub](https://github.com/Thrax37/was-master). It also contains two samplebots, written in Java. 
To make it run, check out the project and open it in your Java IDE. The entry point in the `main` method of the class `Game`. Java 8 required.
To add bots, first you need either the compiled version for Java (.class files) or the sources for interpreted languages. Place them in the root folder of the project. Then, create a new Java class in the `players` package (you can take example on the already existing bots). This class must implement `Player` to override the method `String getCmd()`. The String returned is the shell command to run your bots. You can for example make a Ruby bot work with this command : `return "C:\Ruby\bin\ruby.exe MyBot.rb";`. Finally, add the bot in the players array at the top of the `Game` class.
# Rules
* Bots should not be written to beat or support specific other bots.
* Writing to files is allowed. Please write to"yoursubmissionname.txt", the folder will be emptied before a game starts. Other external resources are disallowed.
* Your submission has 1 second to respond.
* Provide commands to compile and run your submissions.
# Supported Languages
I'll try and support every language, but it needs to be available online for free. Please provide instructions for installation if you're not using a "mainstream" language.
As of right now, I can run : Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C++ 11.
# Final results
These are the results of 100 games (points are added up) :
```
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
```
Individual results of the games are available here : <http://pasted.co/63f1e924> (with starting coins and number of rounds per game).
A bounty of 50 reputations is awarded to the winner : **Bird In The Hand** by [Martin Büttner](https://codegolf.stackexchange.com/users/8478/martin-b%C3%BCttner).
Thank you all for your participation, see you next KOTH~
  
[Answer]
# Oracle, Python 3
Update: changed the order of the various tries to favor low pile of coins over rotations.
```
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])
```
Tries every single possible output and keep the one that yield the maximum amount of points for this turn.
[Answer]
## Bird in the Hand, Ruby
```
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]}
```
If neither of us has a bug in their programs, the main algorithm of this is likely very similar to Mathias's Oracle. Based on the assumption that prior to the final round we can't know which coins we'll end up with, we evaluate the current set of moves purely based on the points received immediately, ignoring completely what sort of coins we'll end up with. Since there are only **143 = 2744** possible move sets we can easily simulate all of them to figure out how many points they'll bring.
However, if a move set ends the game (either because it reduces the global pot to zero, or because this is round 50 and we're the last one to move), then it also takes into account the coins owned at the end of the move set to determine the move set's value. I first considered terminating the game whenever possible, but this would result in the horrible move `333` when there are only 9 coins left in the pot.
If there are multiple move sets giving the same result, we choose a random one. (I might change this to bias it in favour of game-terminating move sets.)
[Answer]
## Greedy Rotation, Ruby
```
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
```
This is quite similar to ArtOfCode's approach, except that this checks from which neighbour we can get more points, and it chooses `C` instead of `F` if we end up with 3 or more coins after the rotation.
After writing this up, I'm pretty sure that a better approach would be just to greedily pick the best out of all moves every time, preceding rotation by taking if possible (instead of sticking to a fixed "get unflipped, rotate, get rid of unflipped" pattern).
This also doesn't take into account the implicit points represented by the coins actually owned (based on the assumption that the game is going to last enough rounds that I likely won't end up keeping my coins anyway).
[Answer]
## Flipper, Python 2
Flipper gathers coins and tries to turn unflipped to flipped. Flipper is not a smart player but tries to be a positive force in the game.
```
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))
```
Flipper just needs the `python flipper.py <arg>` to run.
[Answer]
## SimpleBot, Python 3
SimpleBot is, well, simple. He's worked out one strategy and he's going to stick with it.
To run:
```
python3 main.py
```
where the contents of the `main.py` file is:
```
def main():
    print("3RF")
if __name__ == "__main__":
    main()
```
[Answer]
## Balance, Lua
Balance will try to keep the balance in its token, minimizing the loss in case someone uses the `R` and `T` actions against him.
He thinks this style of life is the true one and should be enforced to anyone that doesn't keep a good balance of flipped/unflipped coins, so everyone close to him will be punished as soon as it could make them lose points.
He needs the following command to run:
```
lua balance.lua
```
Where the file balance.lua contains the following piece of code:
```
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)
```
[Answer]
# The Janitor, Python 3
He tries to clean the mess the other players make with all these coins and put them back into pool.
```
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));
```
He tries to give back all his unflipped coins, if he has some stuck flipped coins he will unflip them and if he gets rid of all his coins he will get somebody's else.
[Answer]
# Crook, 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=""))
```
To run: `Rscript Crook.R`
Basically it exchanges its coins with its neighbours only if the exchange is uneven in its favour. If no beneficial exchange is possible, then it exchanges coins with the global pile in a way that keeps its ratio intact but generate some points.
**Edit:** I added a little bit of depth to this bot by making it check the next and previous 2 and 3 player stacks instead of just the next one and check if, overall, it is beneficial to rotate that many times.
**2nd Edit**: Following @MartinBüttner's idea, the bot now performs a "RT", or "TR", if it would be beneficial for him more than for its neighbours (if I didn't mess up in implementing it :) ).
[Answer]
# Jim, Ruby
based on Martin Büttner's *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]
```
will rotate one way or the other, depending on what will give him the most points compared to the best other player. Then, he flips for quick cash.
[Answer]
## TraderBot
This bot tries to rotate whenever it is the one that takes the most points in that action. If it cannot rotate then tries to get rid of the unfliped coins or take a few more to change them in the following actions.
```
import java.util.ArrayList;
```
import java.util.List;
public class 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();
            }
        }
    }
}
}
```
To run: Just add it to the same folder as the default bots and then create the following class
```
package players;
import controller.Player;
public class TraderBot extends Player {
    @Override
    public String getCmd() {
        return "java TraderBot";
    }   
}
```
Then add that class to the `Player[] players` array.
[Answer]
## Wheeler
Wheeler calculated the best possible move for it when rotating the coins.
```
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();
            }
        }
    }
}
}
```
[Answer]
# Saboteur, Python 2
```
import random
moves = '3R'
print '33' + ''.join(random.choice(moves))
```
The randomness means it probably won't sabotage very well, but later I think I'll have it wait til the 'end' (how many turns/coins are left) and THEN rotate, after looking at the nearby reachable players to steal from... actually only doing one rotation seems really poor, considering other people are also likely to use rotations. I don't think this'll work very well...
[Answer]
## SecondBest, Python 3
This program will go through all possible 3 move combinations and choose the second-best one.
Because if you have the perfect move, it's probably a trap.
Edit: removed commented-out input
```
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])
```
Edit: The code was printing a random legal move. It should now be returning the second best result.
[Answer]
# Devil's Bot
Although its output is only half the devil's number, the results should be quite disastrous. Taking 9 coins each turn, it eventually exhausts the pile of coins. Since this bot never flips any of the coins it takes, it is extremely bad for anyone else sitting next to it when there is a rotation (-9 points for each turn taken by this bot).
```
print("333")
```
Command: `python3 devil.py`
I hope to make some real bots later on.
[Answer]
## Remember Me, Python 3
This program contains a significant amount of inbuilt data from a test against the fixed SecondBest bot. 
It *should* learn about what moves are the best to use, but it does not use other players' input.
Edit: removed unnecessary point calculation 
Edit: uncommented player input
```
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])
```
]