22
3
This is a King of the Hill challenge in a round robin. It's a battle to find the best gunman of the west!
To be able to compete in this contest you need to make two functions. The first one sets the attributes of your gunman and the second is the main logic function for the gunman.
Attribute Function
function () {
var bot = {
name: "testBot",
numbOfBullets: 7,
reloadSpeed: 1,
shotsPerTurn: 1,
moveSpeed: 2
}
return bot
}
The attribute function includes 5 variables that you will need to set according to some rules (with the exception of name
that can be any string). You must spend a total of exactly 15 points on your gunman -- gunmen that do not spend all 15 points are not eligible. Here is how the attributes work:
numbOfBullets
- defines how many bullets your gun holds.The initial and minimum value of
numbOfBullets
is 1. Each additional bullet costs 1 point with the maximum being 16 bullets with 15 points spent.reloadSpeed
- defines how many turns your gunman needs to reload his gun after he ran out of bullets.The base and maximum value is 4 with the minimum being 1. Decreasing this attribute by 1 costs 2 points.
shotsPerTurn
- defines how many times your gunman can shoot in one turn.The base and minimum value is 1. Each increase by 1 costs 3 points so you can have a maximum of 6 shots per round with 15 points spent. Raising this attribute above
numbOfBullets
is counter productive since you can't shoot more bullets then your gun can hold.moveSpeed
- defines how many spaces your gunman can run in one turn.The base and minimum value is 1. Each increase by 1 costs 3 points with a maximum of 6 speed with 15 points spent. The gunman can run either left or right every turn up to a maximum of his move speed. He can also stand still which gives him a bonus (more on this later).
The example function above has 6 points spend on bullets, 6 points spend on reload speed and 3 points spend on movement.
Main function
function main(bulletsLeft, yourShots, enemyShots, yourMovement, enemyMovement) {
var shots = [];
shots.push(Math.floor((Math.random() * 24) + 1));
var move = yourMovement[yourMovement.length - 1] + 2
var play = [];
play.shots = shots;
play.move = move;
play.reload = false;
return play;
}
Parameters:
bulletsLeft
, number of bullets left in your gunyourShots
, this is a array of arrays of all the past positions your gunman has fired at.Example for a gunman who can shoot 1 bullet per round:
[[12],[4],[22],...]
Example for a gunman who can shoot 3 bullets per round:
[[12,13,14],[11,15,16],[9,14],...]
enemyShots
- same as above but for your enemyyourMovement
- an array of all your past movement positionsenemyMovement
, same as above but for your enemy
What you need to return:
You are required to return a variable which has 3 attributes:
shots
- an array of numbers which determine at which space/s your gunman will shootmove
- a single number that determines to what space your gunman will try to move toreload
- a true/false value with which you can make your gunman reload
The Duel
The contest follows a round robin 1 versus 1 system. Each gunman has 50 rounds against every other gunman. A round lasts until someone is hit by a bullet or until 66 turns have passed (a turn is when both players have shot).
The gunman can earn 2 points by killing their opponent, 1 point if they both die in the same turn or 0 points if they reach the 66 turns limit. The shooting field is 24 spaces width (1-24 inclusive). To hit a player and win a round you need to shoot at the same space as he is currently standing on.
Here is a step by step guide on how a duel works. This also covers all invalid commands and special rules:
- At the start of each duel both players are put on space 12 and their revolvers are fully loaded
- The main function is called and the gunman make their first move command and choose where they want to shoot
- First the gunmen move to their new location. If any invalid input is made at the move command (positions lower then 1 or higher then 24 or they moved more spaces then they are allowed too) they stay at the same position.
- Next reloading is checked, if you ran out of bullets the previous turn or you called reloading yourself your gunman goes into the reload cycle. He is reloading for as many turns as you set your
reloadSpeed
value. If you decided to stand still (returning the same space integer as you where standing on before or just returning a invalid value) you reload counter goes down for 2 turns instead of one. - Now comes checking your shooting values, every turn you can enter as many shooting location as you like they will always be cut off to the actual valid amount which is determined by: The number of shots per turn and the number of bullets in your revolver (whichever is lower). Your
shotsPerTurn
value is increased by 1 if you decide to stand still this turn, so you can make a extra shot if you decide to stand still. If you are in the reload cycle you have 0 shots. Now comes the actual shooting, there are 2 ways this can go down. If both gunman have the same movespeed stat then they both shoot at the same time and can both kill each other at the same time. In the case that they have different movespeed stats the bot with the higher movespeed stat starts shooting first and if he kills his opponent he wins this round. If the gunman can shoot one or more bullets in one round then it follows the same rules as above except in more cycles as a example: Lets say that bot1 has 3 bullets and is faster and bot 2 has 2 bullets then it would go like this:
Bot1 shoots, Bot2 shoots cycle 1 Bot1 shoots, Bot2 shoots cycle 2 Bot1 shoots cycle 3
This would look the same if they had the same movespeed only that if now Bot1 hit Bot2 in the same cycle Bot2 could also hit Bot1 and it would be a tie.
RULES
First I am copying some rules from Calvin's Hobbies' entry that also apply here.
When declaring a new JavaScript variable, you must use the var keyword. This is because a variable declared without var becomes global rather than local, so it would be easy to accidentally (or intentionally) mess with the controller or communicate freely with other players. It has to be clear that you aren't trying to cheat.
When declaring functions it is best to use the var keyword as well, i.e. use var f = function(...) {...}
instead of function f(...) {...}.
I'm not entirely sure why, but sometimes it appears to make a difference.
In your code you may not...
- attempt to access or modify the controller or other player's code.
- attempt to modify anything built into JavaScript.
- make web queries.
- do otherwise malicious things.
My additional rules:
- The users can create as many gunman as they want and change their functions for any period of time
- I will remove any entry from the game that either takes a excessive amount of time or tries to cheat in any way that I see fit
- The names of the attributes that your function need to return has to be the same as in the examples with the same structure!
Your answer should be in this format, the first function being the attribute function and the second being the logic function. Notice that I used an exclamation mark because if you just make new lines between code blocks the parser wont see two different code blocks so you have to use any symbol(just use a exclamation mark) to seperate them:
var bot = {
name: "testBot",
numbOfBullets: 7,
reloadSpeed: 1,
shotsPerTurn: 1,
moveSpeed: 2
}
return bot
var shots = []
var testBot_moveUp = true
if(Math.random() * 2 > 1)
testBot_moveUp = false
shots.push(Math.floor((Math.random() * 24) + 1))
var move = 0
if (testBot_moveUp)
move = yourMovement[yourMovement.length - 1] + 2
else
move = yourMovement[yourMovement.length - 1] - 2
move = 12
var play = []
play.shots = shots
play.move = move
play.reload = false
return play
And here is the controller: GAME CONTROLLER. Just open the link and wait for the bots to load, then select which one you want in the fight (probably all) and press the start button.
I also put in a testbot as my answer which will compete, it also serves as a example on how the structure of the answer should look like. As a note, if you make a small mistake and edit your answer stackexchanges algorithm might not pick it up right away and the site that the controller uses which is generated by stackexchange isnt updated(but will later or if you make bigger changes which i suggest doing, just add some text at the end). Here is the site: codelink
I don't seem to be able to get the two bots fighting each other at the moment- if I have them both selected, pressing start doesn't seem to do anything and I'm not sure whether that's my bot being wrong or the controller taking a long time – euanjt – 2015-06-14T13:54:52.100
Yea as i explained at the end of my question when you edited your answer it didnt edit it yet in the stackexchange code generator because it didnt notice that there was a change, if you add some text at the end of your answer it should work – Vajura – 2015-06-14T14:07:22.240
Oh nevermind you still have the error "eemyMovement" in your code, you also have some different errors in your code like "play.reaload" – Vajura – 2015-06-14T14:07:43.937
1I think (fingers crossed) I've corrected those errors- it's just hard to find the errors if the controller doesn't tell me that I didn't provide the correct output and just silently does nothing – euanjt – 2015-06-14T14:23:14.113
"Math.randome", just open the debug console m8 :) – Vajura – 2015-06-14T14:25:47.527
8You can use
<!---->
to separate codeblocks "invisibly" (without the!
). – KRyan – 2015-06-14T17:03:54.527When i run the controller i get "Uncaught TypeError: Cannot read property 'log' of undefined(anonymous function) @ VM205:95` – Scimonster – 2015-06-14T20:08:03.213
yes that is because of @TheE submission, he added console.log and it broke it should be fine once it updates – Vajura – 2015-06-14T20:44:42.207
"25 spaces width (1-24 inclusive)" - 1-24 is only 24 fields, though... Did you mean 0-24? If 0 isn't a field, then the playing field is asymmetrical and there is more space on the right side. – QuadrExAtt – 2015-06-15T07:57:07.940
Oh i meant 24 spaces yes the 25 is a typo. Does it matter that its asymmetrical? – Vajura – 2015-06-15T08:06:36.197
Something with the controller seems off when using more than two players. If I do 1:1 I get different results/winners than when I mark 3 or 4 players at once. – QuadrExAtt – 2015-06-16T08:02:44.903
The more players you use the more points the each bot can gain, EDIT ah i see what you mean, will look into it – Vajura – 2015-06-16T08:05:40.747
1Found the error. Change "play1 = maskedEval(players[a].code, params)" to "play1 = maskedEval(playingPlayers[a].code, params)" - same for play2 – QuadrExAtt – 2015-06-16T08:14:57.727
nice catch thanks, that fixed it yea. – Vajura – 2015-06-16T08:47:17.933
What are "setMsg" and "getMsg"? – QuadrExAtt – 2015-06-16T09:13:57.253
Let us continue this discussion in chat.
– Vajura – 2015-06-16T09:29:42.130Regarding
– gcampbell – 2016-06-10T10:42:51.947var f = function(...) {...}
vsfunction f(...) {...}
, you might be interested in this answer on SO.Awwwh... "Can't access any of your opponent's code"... And here I was ready to write an extremely cheat-y reflection answer. Then again... Someone else would've also done that and we would've had two reflceto-bot gunners, getting nowhere because they have to wait for each other to know what they're doing to do anything lol. – Magic Octopus Urn – 2017-04-19T19:24:02.420