クリッカーゲームを作ろう!!

| コメント(0) | トラックバック(0)

CookieClickerが流行ってだいぶ経ちますが、みなさんはクリッカー病は治りましたか?
私は未だ完治していません(^^;
クッキーは作らなくなりましたが、似たようなゲームを見つけるとついついやってしまいます。
これをどうやって治すか。。。自分で作ってしまえ!!
作っている間のテストプレーをやりすぎて飽きるというよくあるパターン狙いです(笑)

さっそく作成開始。
クリッカー系のゲームは何と言っても大量にクリックして、大きな数字を扱うのが重要になって来ると思います。
JavascriptのNumberは64bit浮動小数ですので十分大きな数字を扱えますが、精度がよろしくありません。
今回はあまり少数点の精度は必要ありませんので、整数に限った精度のよいものを作ってみました。
ちょっと長いですが、ソースは以下の通り。

var Decimal = function (v)
{
	this.values = [0];
	
	this.set(v ? v : 0);
};
Decimal.prototype =
{
	set : function (v)
	{
		if (v instanceof Decimal)
		{
			for (var n = 0; n < v.values.length; n++)
			{
				this.values[n] = v.values[n];
			}
			this.values.length = v.values.length;
		}
		else
		{
			var val = parseInt(v);
			if (val < 0) val = 0;
			var n = 0;
			do
			{
				this.values[n++] = val % 1000;
				val = Math.floor(val / 1000);
			}
			while (val);
			
			this.values.length = n;
		}
		
		return this;
	},
	add : function (v)
	{
		if (!(v instanceof Decimal))
			v = new Decimal(v);
		
		var newVal = new Decimal(this);
		
		var vn = 0;
		for (var n = 0; n < Math.max(newVal.values.length, v.values.length) || vn; n++)
		{
			var v1 = newVal.values[n] ? newVal.values[n] : 0;
			var v2 = v.values[n] ? v.values[n] : 0;
			newVal.values[n] = v1 + v2 + vn;
			vn = Math.floor(newVal.values[n] / 1000);
			newVal.values[n] %= 1000;
		}
		
		return newVal;
	},
	sub : function (v)
	{
		if (!(v instanceof Decimal))
			v = new Decimal(v);
		
		var newVal = new Decimal(this);
		
		if (newVal.greater(v))
		{
			for (var n = 0; n < v.values.length; n++)
			{
				if (newVal.values[n] < v.values[n])
				{
					newVal.values[n] += 1000;
					newVal.values[n + 1]--;
				}
				newVal.values[n] -= v.values[n];
			}
			
			while (newVal.values[newVal.values.length - 1] === 0 && 1 < newVal.values.length)
			{
				newVal.values.length--;
			}
		}
		else
			newVal.set(0);
		
		return newVal;
	},
	mul : function (v)
	{
		if (!(v instanceof Decimal))
			v = new Decimal(v);
		
		var newVal = new Decimal(0);
		
		for (var n = 0; n < this.values.length; n++)
		{
			var vn = 0;
			for (var m = 0; m < v.values.length; m++)
			{
				if (!newVal.values[m + n])
					newVal.values[m + n] = 0;
				var value = this.values[n] * v.values[m] + vn + newVal.values[m + n];
				newVal.values[m + n] = value % 1000;
				vn = Math.floor(value / 1000);
			}
			if (vn)
				newVal.values[m + n] = vn;
		}
		
		while (newVal.values[newVal.values.length - 1] === 0 && 1 < newVal.values.length)
		{
			newVal.values.length--;
		}
		
		return newVal;
	},
	divE : function (pow)	// 10のpow乗で割る
	{
		var newVal = new Decimal(this);
		
		while (3 <= pow)
		{
			newVal.values.shift();
			if (newVal.values.length === 0)
			{
				newVal.values.push(0);
				return newVal;
			}
			pow -= 3;
		}
		
		if (pow == 1)
		{
			newVal.values.push(0);
			for (var n = 0; n < newVal.values.length - 1; n++)
			{
				newVal.values[n] = Math.floor(newVal.values[n] / 10);
				newVal.values[n] += (newVal.values[n + 1] % 10) * 100;
			}
		}
		else if (pow == 2)
		{
			newVal.values.push(0);
			for (var n = 0; n < newVal.values.length - 1; n++)
			{
				newVal.values[n] = Math.floor(newVal.values[n] / 100);
				newVal.values[n] += (newVal.values[n + 1] % 100) * 10;
			}
		}
		
		while (newVal.values[newVal.values.length - 1] === 0 && 1 < newVal.values.length)
		{
			newVal.values.length--;
		}
		
		return newVal;
	},
	equal : function (v)
	{
		if (!(v instanceof Decimal))
			v = new Decimal(v);
		
		return this.toString() == v.toString();
	},
	greater : function (v)
	{
		if (!(v instanceof Decimal))
			v = new Decimal(v);
		
		var v1 = this.toString();
		var v2 = v.toString();
		
		if (v1.length == v2.length)
			return v2 < v1;
		
		return v2.length < v1.length;
	},
	toString : function ()
	{
		var ret = "" + this.values[this.values.length - 1];
		for (var n = this.values.length - 2; 0 <= n; n--)
		{
			ret += "," + ((this.values[n] + 1000) + "").substr(1, 3);
		}
		
		return ret;
	}
};

基本的な考え方としては、3ケタごとにカンマで区切って表示したいので、3ケタごとに変数に格納してそれらを配列として扱います。
あとは適当に加算、減算、乗算を行えるようにしました。
ちゃんとした除算は必要なさそうなので実装していませんが、一応少数を扱いたくなることを想定して、10の乗数で割れるようにしました。
あと、比較もできるように。
これだけあれば作れそうな気がしてきます、というかすでにできたような気になってきました(^^;
動作確認

トラックバック(0)

トラックバックURL: http://murakya.net/mt/mt-tb.cgi/52

コメントする

オリジナルゲーム

オンラインツール