Arrangement Game

I code for my friends

by asemahle

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/chance/1.0.3/chance.min.js"></script>
<div id="app">
  <h1>Arrangement Puzzle</h1>
  
 
  <label for="num-numbers">Number of numbers to arrange:</label>
  <input id="num-numbers" type="number" v-model="numNumbers"><br>
  
  <label for="num-swaps">Number of swaps per operation (OP):</label>
  <input id="num-swaps" type="number" v-model="numSwaps"><br>
  
  <label for="num-ops">Number of operations:</label>
  <input id="num-ops" type="number" v-model="numOps"><br>
  
  <label for="num-ops-to-apply">Number of operations to apply:</label>
  <input id="num-ops-to-apply" type="number" v-model="numOpsToApply"><br>
  
  <button @click="applyOps">Apply operations {{ numOpsToApply }} times</button>
  <button @click="generateOps">Generate new operations</button>
  <button @click="setNumbers">Reset</button>
  
  <div class="container">
    <span class="number" v-for="number in numbers">
        {{ number }}
    </span>
  </div>
  
  <button @click="applyOperation(operation, false)" v-for="operation in operations">
    Apply OP {{ $index + 1 }}
  </button><br><br>
  
  <button @click="showOps = !showOps">Show operations?</button>
  <div v-show="showOps">
    <div v-for="op in operations">
      <h3>
        OP {{ $index + 1}}
      </h3>
      <ul class="list-group">
        <li class="list-group-item"v-for="swap in op">
          Swap position {{swap[0]}} with {{swap[1]}}
        </li>
      </ul>
    </div>
  </div>
  
</div>

CSS

.container {
  margin: 20px;
}

.number {
  font-size: xx-large;
  margin: 25px;
}

JavaScript

var app = new Vue({
	el: '#app',
  
  data: {
  	showOps: false,
  	numNumbers: 5,
    numSwaps: 2,
    numOps: 2,
    numOpsToApply: 5,
    numbers: [],
    operations: [[]],
  },
  
  methods: {
  	setNumbers: function() {
    	this.numbers = [];
    	for (let i = 0; i < this.numNumbers; i++) {
      	this.numbers.push(i);
      }
    },
    
    applyOps: function() {
    	undo = [];
    	for (let i = 0; i < this.numOpsToApply; i++) {
      	let op = chance.integer({min: 0, max: this.operations.length - 1});
        this.applyOperation(this.operations[op], true);
        undo.push(op + 1);
      }
      console.log("Undo with: " + undo.reverse());
    },
    
    applyOperation: function(operation_, isReversed) {
    	let operation = operation_.slice();
      if (isReversed) { operation.reverse() };
      
    	for (let swap of operation) {
      	num1 = this.numbers[swap[0]];
        num2 = this.numbers[swap[1]];
        this.numbers[swap[0]] = num2;
        this.numbers[swap[1]] = num1;
      }
      this.numbers = this.numbers.slice();
    },
    
    generateOps: function() {
    	this.operations = [];
    	for (let i = 0; i < this.numOps; i++) {
      	this.operations.push([]);
        for (let j = 0; j < this.numSwaps; j++) {
        	this.operations[i].push([
          	chance.integer({min: 0, max: this.numbers.length - 1}),
            chance.integer({min: 0, max: this.numbers.length - 1})
          ])
        }
      }
      this.operations = this.operations.slice();
    }
  },
  
  watch: {
  	numNumbers: function() { this.setNumbers(); this.generateOps(); },
    numSwaps: function()   { this.generateOps(); },
    numOps: function()     { this.generateOps(); },
  },
  
  ready: function() {
  	this.setNumbers();
		this.generateOps();
  }
  
});