2017-04

収支管理システム構築5 景品計算2

20日に行ったアイランド秋葉原店での実戦にて気付いたこと。

3892枚で82.5kだったのですが、
余り枚数が0.5枚単位でした。

前々回の方法でうまく計算できるのか、ちょっとやってみたいなと。
ただ、XX枚交換というのは適切ではなくなっているので、式を変えつつ。

(例 3892枚 1k/47枚)

景品設定:5500,1500,1000

0:事前情報収集
・枚数変換
景品金額/1000*交換枚数=必要枚数
5500:5500/1000*47=258.5
1500:1500/1000*47=70.5
1000:1000/1000*47=47

・最低枚数(この枚数に満たない場合0円)
[共通]
60

・最大公約数(この枚数単位で計算)
[共通]
ユークリッドの互除法というのを用いて計算
小数部が無くなるまで10倍を繰り返し、整数にした段階で計算。
出た結果をそれまでの倍率で割る。

258.5 * 10 = 2585
70.5 * 10 = 705
47 * 10 = 470

2585,705,470の最大公約数 => 235
235/10 = 23.5

1:最低枚数以外の景品で取りうる最大値を設定
そこから最も少ない単位を1つずつ増やし、範囲内に収まるかどうかを調べる。
終了は合計枚数を超えるまで。
対象が見つからない場合は値を減らしていく。

[例]
258.5*15...OK

258.5*15
70.5*0
47*0
=3877.5枚
余り14.5枚
2.出た景品数と金額を掛けたものを合計する。
[例]
5500*15+1500*0+1000*0=82500円

計算終わって気付きましたが
例としては一番面白みがないパターンじゃないですか・・・。

枚数換算する際に、整数前提としないこと、
ユークリッドの互除法は整数を用いて行うので、整数になるまで倍率をかけること。

この辺を考えられていれば特に問題なく計算できそうです。

収支管理システム構築4 やってみたいことやりたいことを連ねてみる。

収支管理システムというカテゴリタグを切ってますが、
結局のところ何がしたいのか?を考えてみたいと思います。

自分のよく使う手法は、とりあえず箇条書きした後に分類分けしてみること。

・実戦の結果をまとめたい
・一定期間でどのような収支になっているのかを知りたい
・どの機種で勝ててるか、負けてるかを知りたい
・何か勝ち負けに傾向があるかどうかを知りたい
・差枚数での収支を知りたい
・現金収支を知りたい
・店ごとの戦績を知りたい
・どの機種をどれだけ遊んだかを知りたい
・毎月の月間収支をグラフィカルに見たい
・レートに関して最適化された収支を見たい
・レート毎の情報を知りたい
・1日実戦の記録を簡単にまとめたい
・目標を設定して管理できるようにしたい
・ブログへの反映を簡単にしたい
・Web上で収支入力を行えるようにしたい
・スマートフォンから入力できるようにしたい
・貯玉、端玉にも正確に対応したい
・今まで結構古いものばかり扱っているので新しい技術を使って開発してみたい

とりあえず5分でこんな感じですかね。
後半は色々とセキュリティとかなんやら面倒な感じもありますが・・・

では、現状の収支のまとめ方はどうなっているのか。

[ホールにて]
・着席
→機種名と開始時間、開始G数などを記録

・事象発生(事象:プレミア、悲しみの画像、チャンスゾーンやボーナス当選など)
→事象を記録、画像を撮る

・終了時
→投資と回収、終了時間を記録

[自宅にて(定期)]
・Postgresqlへのデータ追加用のExcelに転記、反映

・画像を転送、Web用に編集し、記事にしてアップロード

・毎月初めに月間収支をまとめる

定期的にやってることがもうちょっと楽になればいいなぁ、
という感じですかね。
せっかくPCあるので有料サービスには頼りたくないし、
何のために技術者やってんの、ってのもあるので・・・

今は言語もシステムもフリーの方が多いですから、
わりとやる気になれば何でもできるんじゃないかな、と。

収支管理システム構築3 ユークリッドの互除法

ユークリッドの互除法について触れます。

最大公約数を計算する際、
まず浮かぶのが対象の素数を求め、
共通する素数の最大値を最大公約数とするもの。

素数を求めるプログラムを組むのがとても面倒。
出来ないことはないと思いますが、まぁ面倒。・・・コピーしてもいいんですけどね。

そこで最大公約数で検索をかけると出てくるユークリッドの互除法。

これによると、以下の様な感じで計算ができるとのこと。

●2つの数の場合
・javaで表現するとこんな感じ。
resultには再帰的に呼び出した結果、最終的に残ったsmallが帰ってきます。
	public static int gcd(int a, int b) {

		// 0の場合、反対方向の値を結果として返す。
		if (a == 0) {
			return b;
		}
		if (b == 0) {
			return a;
		}

		int result = 0;

		// 値の大小を判別。
		int large;
		int small;
		if (a > b) {
			large = a;
			small = b;
		} else {
			large = b;
			small = a;
		}

		// 余り計算と再帰判定
		int odd = large % small;
		if (odd == 0) {
			result = small;
		} else {
			result = gcd(small, odd);
		}

		return result;
	}

●3つ以上の数の場合
・javaで表現するとこんな感じ。
結局は再帰計算を行い、答えを探します。
ガード区は例外投げてもいい感じですね。そもそもダメなので。
	public static int gcd(List<Integer> targets) {
		// ガード句的な感じで
		if (targets == null || targets.size() == 0) {
			return 0;
		}

		int result = 0;

		// 昇順ソート
		Collections.sort(targets);

		// その1番目を用いる
		int small = targets.get(0);

		// 再帰計算用の配列
		List<Integer> workTargets = new ArrayList<>();
		// 余りが0でないものを集めていく
		for (int i = 1; i < targets.size(); i++) {
			int odd = targets.get(i) % small;
			if (odd != 0) {
				workTargets.add(odd);
			}
		}

		// 全て割り切れた場合はその割った数が答え
		if (workTargets.size() == 0) {
			result = small;
		} else {
			// そうでない場合は割った数を配列に加えて再帰
			workTargets.add(small);
			result = gcd(workTargets);
		}

		return result;
	}

※デバッグコード
	public static void main(String[] args) {
		System.out.println(gcd(Arrays.asList(5500, 1500, 1000)));
		// →500
	}

これで多景品時の最低金額の計算ができます。

収支管理システム構築2 景品計算

※業界の人ではないので、計算式は全て我流ですのでご注意下さい。

東京だとこんな感じで見かける景品数表示。

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
大 中 小 || 計
============================================================
3 2 2 || 21500
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

どうやって計算しますか?

今回の検討事項は、景品種類の違いによる価格計算。
確か広島だと100円単位から。
2015年3月時点の東京だと、5500円、1500円、1000円。
といった感じで、場所によって異なります。

フローとしては以下の様な感じでしょうか。
金額ベースでやるか枚数ベースでやるかで変わります。

まずは金額ベース。
(例A:575枚/6枚,例B:1302枚/6枚)
景品設定:5500,1500,1000

0:事前情報収集
・最低金額(この金額に満たない場合0円)
[共通]
1000

・最大公約数(この金額単位で計算)
[共通]
ユークリッドの互除法というのを用いて計算
500

1:価格計算
枚数/(交換率/100)

[例A]
575/(6/100) = 9583.333333 => 9583
[例B]
1302/(6/100) = 21700

2:最低金額以外の景品で取りうる最大値を設定
そこから最も少ない単位を1つずつ増やし、範囲内に収まるかどうかを調べる。
終了は合計金額を超えるまで。
対象が見つからない場合は値を減らしていく。

[例A]
5500*1+1500*2...OK

5500*1
1500*2
1000*1
=9500円
余り83円

[例B]
5500*3+1500*3...NG
5500*3+1500*2...OK

5500*3
1500*2
1000*2
=21500円
余り200円

枚数ベースの方も触れてみます。

(例A:575枚/6枚,例B:1302枚/6枚)
景品設定:5500,1500,1000

0:事前情報収集
・枚数変換
景品金額/100*交換枚数=必要枚数
5500:5500/100*6=330
1500:1500/100*6=90
1000:1000/100*6=60
※ここで端数は出ないはずです。

・最低枚数(この枚数に満たない場合0円)
[共通]
60

・最大公約数(この枚数単位で計算)
[共通]
ユークリッドの互除法というのを用いて計算
30

1:最低枚数以外の景品で取りうる最大値を設定
そこから最も少ない単位を1つずつ増やし、範囲内に収まるかどうかを調べる。
終了は合計枚数を超えるまで。
対象が見つからない場合は値を減らしていく。

[例A]
330*1+90*2...OK

330*1
90*2
60*1
=570枚
余り5枚

[例B]
330*3+90*3...NG
330*3+90*2...OK

330*3
90*2
60*2
=1290枚
余り12枚

2.出た景品数と金額を掛けたものを合計する。
[例A]
5500*1+1500*2+1000*1=9500円
[例B]
5500*3+1500*2+1000*2=21500円

枚数ベースの方が端数の心配がなくていいですね。
最大公約数や景品数で取りうる最大値の決定のアルゴリズムを決めでやるとすごく簡単なのですが、
システム的にはまた変更が行われると面倒です。
あとは端数だけ貯玉とされた場合、その時点での端玉数を把握しておかないとズレます。
後から一覧計算するときにはこのこともとても面倒な事項の1つになりそうです。

一旦これらはSQLのFunctionとして作成してみます。

収支管理システム構築1 現状把握

毎月出力している差枚数情報は、Postgresqlを用い、
個人で設計したDBに対してデータの入力、出力を行っています。

将来的にはWeb上で入力できるようにしたいなと考えながら、今のところSQL文で登録しているのですが、
1年経過した時点で、結構見直しを行う必要が発生しています。

正直、1年経過した時点でここまでの変化があるとは想定していなかったですが、
対応しなければ正しい収支、差枚情報の算出が難しくなります。
(今のところほぼ1店舗、20スロのみで動いているのでそこまでの影響はないですが)

・レートの多様化
→こちらは既に兆候があったので、前回のテーブル定義では以下の考慮をしていました。
4,2,1パチ用、20,10,8,5スロ用交換率
ですが、今後何スロが登場するか全く読めないですし、
柔軟に対応するためにこの定義を拡張する必要があります。

・1k47枚の出現
→ついに貸出枚数が減りました。
20スロといっても、実は47枚の場合、21.27スロなのです。
今後も変動があると想定されるので、こちらも変更が必要です。

また、1k/47枚の場合の差枚数計算をどうするかも問題になります。
現状、5スロの場合は1/4計算といったように、1k/50枚に合わせた差枚数計算を行っていますが、
この場合の考慮をどうするか、ということもあります。
画面上などに出す場合はオプション等で考慮してあげるのが親切でしょうか。
実際、去年は1k/47枚は1k/50枚と同じ扱い、1k/200枚は4分の1計算となっています。

・景品に応じた計算式の確立
→昨年、現金収支は出していません。
全て差枚で計算してしまったため、店舗情報やその時点のレートはわかっているのですが、
金額換算するまでに至っていないのが現状です。

その原因が、景品種類の違い。
大景品、中景品といった感じで扱っているところや、
常に100円から計算しているところがありますので、
ただ計算するだけだと端数が合いません。
端数を合わせるためにはその時代、場所での景品と交換枚数の定義が必要です。
で、計算方法を考えていますがSQL一発にするには結構たいへんそう・・・

こういった点を考慮して、今年の前半で、再度DBの再構成を行おうと思います。
参考になるかは置いておいて、たまにはこういったIT系スロッターらしい記事で空白期間を埋めようかな、と。

«  | ホーム |  »

プロフィール

青竜斬

Author:青竜斬
声優ヲタで萌えスロッターでオーガスト好きでMJプレイヤーなプログラマー、青竜斬が書いております。
プログラマーなので主に文字しか産み出せません。

※当サイトは声優、1986年生まれの方々を応援してます。
現状、スロットネタが多いのでジャンルをギャンブルにしてます。

最新記事

最新コメント

最新トラックバック

月別アーカイブ

カテゴリ

日記 (17)
技術メモ (9)
スロット実戦 (87)
スロット戦績 (30)
スロット雑談 (22)
パズドラ (5)
艦これ (25)
収支管理(パチスロ) (5)
城プロ (2)
MJ (5)
かんぱに☆ガールズ (4)

RSSリンクの表示

カウンター

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する

ブロとも申請フォーム

この人とブロともになる

QRコード

QR