犬を飼いたい社内ニートのブログ

一生懸命作った、クソコードを紹介していくつもりです。

NoxPlayerでアビスリウムのイベントアイテム回収を自動化してみた

アビスリウムとは

こんにちは、犬を飼いたい社内ニート Castoroides です!
突然ですが、スマホゲームのアビスリウムってご存じですか?

apps.apple.com

ゆっくり休みながら楽しむゲーム

「アビスリウム – タップで育つ水族館」は、忙しい日常で疲れたあなたを癒す放置型癒し系ゲームです。癒しが必要な可愛い魚たちを深海のアクアリウムに招き、癒されながら成長の喜びを味わうことができます。"静かな水族館を賑やかにし、干からびた日常に癒しを与え、水族館を成長させながらたくさんの可愛い魚たちに出会える、放置型癒し系ゲーム「アビスリウム」をあなたにおすすめします。"


雑に言うと、タップしまくって水族館を成長させるゲームです。


今回はそのタップゲーのタップ要素をNoxplayerを使って自動化したいと思います。

NoxPlayerについて

まずはNoxPlayerについて知らない人も多いと思うので簡単にご説明します。

NoxPlayerはAndroid アプリを PC で動かすための無料ソフトウェアです。
jp.bignox.com

PCに接続しているキーボードやマウスが利用できるので、ゲームによっては快適にプレイできます。

なにより、マクロを組むことによって単純操作を自動化することができるんです。
また、スクリプト」という機能で、Excelのマクロのように操作を記録することもできます。


単純操作の自動化

それではNoxPlayerのマクロ機能を使用し、さっそくアビスリウムを自動化していこうと思います。

Step 1 仮想キーの作成

まず、Noxplayerでアビスリウムを開きます。
f:id:castoroides_uky:20211016222248p:plain

右上に「仮想キーの設定」があるのでこちらをマウスでクリックします。
f:id:castoroides_uky:20211016222538p:plain

「マクロ」をクリック
f:id:castoroides_uky:20211016224441p:plain

作成されたcolliderを確認した後、マクロを実行させるショートカットキーを設定できます。
f:id:castoroides_uky:20211016225307p:plain

今回はCtrl+Aに設定します。
f:id:castoroides_uky:20211016225851p:plain


Step 2 マクロの設定

ショートカットを設定した後は右下の鉛筆マークをクリックしてのエディターを開きます。

マクロエディターでは、例えばクリック操作をさせたい場合はクリックの X か Y どちらかのテキストボックスをアクティブにした状態で、実際にゲーム画面をクリックすることで該当の座標が入力されます。その状態で以下画像右の「+」ボタンを押すとマクロキーエディットにコードが追加されます。
f:id:castoroides_uky:20211016230422p:plain

その他いろいろとできそうなパーツが揃っていそうですが、今回は「クリック」と「ループ」以外使わないので割愛です。

要するに、今回組んだのはイベントアイテムやその他時間経過により出現するアイテムが取得できるように、まんべんなくクリックする座標を散らせてその操作を無限ループさせるというマクロです。

以下、コードの全容です。

loop 1000000

click 50 200
click 100 200
click 150 200
click 200 200
click 250 200
click 300 200
click 350 200
click 400 200
click 450 200
click 500 200

click 50 300
click 100 300
click 150 300
click 200 300
click 250 300
click 300 300
click 350 300
click 400 300
click 450 300
click 460 320
click 500 300

click 50 400
click 100 400
click 150 400
click 200 400
click 250 400
click 300 400
click 350 400
click 400 400
click 450 400
click 500 400

click 50 500
click 100 500
click 150 500
click 200 500


click 350 500
click 400 500
click 450 500
click 500 500

click 50 600
click 100 600
click 150 600
click 200 600
click 250 600
click 300 600
click 350 600
click 400 600
click 450 600
click 500 600

click 190 800

loop 1000000でそれより以下の処理を1,000,000回ループさせています。(無限ループのやり方がわからなかったので…… 、どなたか教えてください)

あとは画面の左上から右下までをまんべんなくクリックさせています。
ところどころ虫食い状態になっていますがこれは、動画視聴の宝箱等を避けるためです。降りてくる最中のものはクリックしちゃいますが。

最後のclick 190 800は、動画視聴の宝箱をクリックしてしまったときに「取り消し」を選択できるように加えています。


動かしてみた

動かしてみるとこんな感じ!

youtu.be



これでイベントも楽々走り切れそうです!
ぜひコードをコピーして使ってみてくださいね^^

フリーセルクリア後のシャーってなるやつ作ってみた

懐かしのフリーセルについて

こんにちは、犬を飼いたい社内ニート Castoroides です!
皆さんは昔フリーセル(またの名をソリティア)やっていましたか?

私はというと、小学生時代はいつもお世話になっていました!
(どちらかというと、ピンボールの方をやっていましたが…)


今のフリーセルはストアからゲームをインストールする必要があるみたいですね。
www.microsoft.com



これですこれ!良かった、まだ健在みたい!
f:id:castoroides_uky:20211014164927p:plain


と、思ったら別のアニメーションも用意されているみたい😊
f:id:castoroides_uky:20211014160618p:plain

ということで、今のフリーセルのクリア後アニメーションはいくつかパターン化されているみたいですね!


画像撮影中、フリーセルを思ったより楽しんでしまいましたが、
ここからが本題です。

このアニメーションJavaScriptで組めないかな?

このトランプがシャーってなるやつをいつでも見れるようにJavaScriptで組んでいきたいと思います。



2日後


微調整している間にとんでもなく時間がかかってしまった…
とりあえずできたのでスクリプト全体を以下に記載します!

今回作成したコード全体

<script>
// 画像読み込み
let imageWidth = 409
let imageHeight = 600
data = new Array(
	"https://3.bp.blogspot.com/-x1YD4kp-X9E/WQBAA3RKDbI/AAAAAAABD9M/5K8vEH6kYSo5M9r2jzxheGlnup2k-El5gCLcB/s800/card_heart_02.png",
	"https://2.bp.blogspot.com/-S-31SRfkS1o/WQBAEtCo1nI/AAAAAAABD98/fzjjCIIibhMkeoKx9NfyTo3i1TjRaONPQCLcB/s800/card_spade_01.png",
	"https://4.bp.blogspot.com/-hIKME4x_kbQ/WQA_3IHzulI/AAAAAAABD7o/Ft4JOq2ydaEHteja59Zzv_i3ieXnmONwwCLcB/s800/card_club_03.png",
	"https://4.bp.blogspot.com/-WNnDDDnVkrs/WQA_9vUTTJI/AAAAAAABD8g/PSyYSizOnVkaC37L7bLn82Ex83Tvm0BKACLcB/s800/card_diamond_04.png",
	"https://4.bp.blogspot.com/-bvSGYORb6Xg/WQBAF61kUOI/AAAAAAABD-Q/SalVkKKYYt85TNJJsOjmgNwfT0ao3foewCLcB/s800/card_spade_05.png",
	"https://3.bp.blogspot.com/-w5tuOxBszlU/WQBABseF49I/AAAAAAABD9c/9yF8y-6012MKF5UlSz-dxORnZU_YhEuxgCLcB/s800/card_heart_06.png",
	"https://2.bp.blogspot.com/-LXJw0prlZp0/WQA_6wZyEVI/AAAAAAABD74/eFWVHzCtgLMj_C-JPzjOd7YfhiveHytlQCLcB/s800/card_club_07.png",
	"https://1.bp.blogspot.com/-FZGbdtedARU/WQA__nBH5iI/AAAAAAABD84/X9BsjJbBLZcuGBr5VT2EeisGjlp0wtJpwCLcB/s800/card_diamond_08.png",
	"https://1.bp.blogspot.com/-lYcdLoEoqhk/WQBAGkz_02I/AAAAAAABD-Y/BzeTL07VRhc9viqmclMywil_LqOdQGL5QCLcB/s800/card_spade_09.png",
	"https://4.bp.blogspot.com/-Dj2Yzi1XR-E/WQBADWUni-I/AAAAAAABD9s/2Cy3plnNZGwt9sV3vDO4eCvJSSg9DGx-wCLcB/s800/card_heart_10.png"
)
imag= new Array();
for (i=0; i<data.length; i++){
	imag[i] = new Image();
	imag[i].src = data[i];
}

// getContextメソッドで描画機能を有効にする
var canvas = document.querySelector("canvas");
var context = canvas.getContext('2d');

// canvas の幅と高さの指定
var canvas = document.getElementById("canvas");
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

// トランプのクラス
var Card = function(scale, color, vx, vxs, vy, gv) {
	this.scale = scale; // 縮尺
	this.dstWidth = dstWidth;
	this.dstHeight = dstHeight;
	this.kind = kind; // トランプの種類
	this.vx = vx; // X速度
	this.vxs = vxs; // 退場時の速度
	this.vy = vy; // Y速度
	this.gv = gv; // 重力
	this.position = { // 位置
		x: 0,
		y: 0
	};
};

// 変数宣言
var Cards = []; // トランプをまとめる配列
var kind;
var scale;
var dstWidth;
var dstHeight;
var x;
var xs;
var y;
var g;
var indx;
var startDate = new Date();
var interval = 2000;

// ループ処理
function animloop(){
	
	requestAnimFrame(animloop);
	
	// カードの追加
	if(new Date() - startDate > interval){
		startDate = new Date();
		
		// 詳細値の作成
		//Math.random() * (max - min) + min;
		kind = Math.random() * 10;
		scale = Math.random() * (0.25 - 0.1) + 0.1;
		dstWidth = imageWidth * scale;
		dstHeight = imageHeight * scale;
		x = Math.random() * (10) -5;
		xs = x / 10;
		y = Math.random()* 9 + 4;
		g = Math.random()* 0.2 + 0.3;
		indx = Cards.length;
		
		Cards[indx] = new Card(scale, kind, x, xs, -y, g);
		Cards[indx].position.x = Math.random() * (canvas.width);
		Cards[indx].position.y = 100;
	}
	// カードの更新
	for (var i in Cards) {
		Cards[i].update();
	}
}

// コピペ from https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

// 座標の更新
Card.prototype.update = function() {
	this.vy += this.gv;
	this.position.x += this.vx;
	this.position.y += this.vy;
	
	// 地面の衝突判定
	if (this.position.y > canvas.height - this.dstHeight) {
		this.vy *= -0.8;
		this.vx *= 0.85;
		this.position.y = canvas.height - this.dstHeight;
		if(Math.abs(this.vx) < 0.8){
			this.position.x += this.vxs;
		}
	}
	this.draw();
};

// canvasに描画
Card.prototype.draw = function() {
	context.beginPath();
	context.arc(this.position.x, this.position.y, this.scale, 0, 2*Math.PI, false);
	context.fillStyle = this.color;
	//context.fill();
	console.log(Math.floor(this.kind))
	context.drawImage(imag[Math.floor(this.kind)], this.position.x, this.position.y, this.dstWidth, this.dstHeight);
};

// アニメーションの起点
animloop();

</script>


■ 解説:画像読み込み

まず、冒頭で画像の読み込み等をしてます。
(いらすとやのお借りしてます)

// 画像読み込み
let imageWidth = 409
let imageHeight = 600
data = new Array(
	"https://3.bp.blogspot.com/-x1YD4kp-X9E/WQBAA3RKDbI/AAAAAAABD9M/5K8vEH6kYSo5M9r2jzxheGlnup2k-El5gCLcB/s800/card_heart_02.png",
	"https://2.bp.blogspot.com/-S-31SRfkS1o/WQBAEtCo1nI/AAAAAAABD98/fzjjCIIibhMkeoKx9NfyTo3i1TjRaONPQCLcB/s800/card_spade_01.png",
	"https://4.bp.blogspot.com/-hIKME4x_kbQ/WQA_3IHzulI/AAAAAAABD7o/Ft4JOq2ydaEHteja59Zzv_i3ieXnmONwwCLcB/s800/card_club_03.png",
	"https://4.bp.blogspot.com/-WNnDDDnVkrs/WQA_9vUTTJI/AAAAAAABD8g/PSyYSizOnVkaC37L7bLn82Ex83Tvm0BKACLcB/s800/card_diamond_04.png",
	"https://4.bp.blogspot.com/-bvSGYORb6Xg/WQBAF61kUOI/AAAAAAABD-Q/SalVkKKYYt85TNJJsOjmgNwfT0ao3foewCLcB/s800/card_spade_05.png",
	"https://3.bp.blogspot.com/-w5tuOxBszlU/WQBABseF49I/AAAAAAABD9c/9yF8y-6012MKF5UlSz-dxORnZU_YhEuxgCLcB/s800/card_heart_06.png",
	"https://2.bp.blogspot.com/-LXJw0prlZp0/WQA_6wZyEVI/AAAAAAABD74/eFWVHzCtgLMj_C-JPzjOd7YfhiveHytlQCLcB/s800/card_club_07.png",
	"https://1.bp.blogspot.com/-FZGbdtedARU/WQA__nBH5iI/AAAAAAABD84/X9BsjJbBLZcuGBr5VT2EeisGjlp0wtJpwCLcB/s800/card_diamond_08.png",
	"https://1.bp.blogspot.com/-lYcdLoEoqhk/WQBAGkz_02I/AAAAAAABD-Y/BzeTL07VRhc9viqmclMywil_LqOdQGL5QCLcB/s800/card_spade_09.png",
	"https://4.bp.blogspot.com/-Dj2Yzi1XR-E/WQBADWUni-I/AAAAAAABD9s/2Cy3plnNZGwt9sV3vDO4eCvJSSg9DGx-wCLcB/s800/card_heart_10.png"
)
imag= new Array();
for (i=0; i<data.length; i++){
	imag[i] = new Image();
	imag[i].src = data[i];
}

// getContextメソッドで描画機能を有効にする
var canvas = document.querySelector("canvas");
var context = canvas.getContext('2d');


■ 解説:クラスの定義

ここはクラスを定義しています。

// トランプのクラス
var Card = function(scale, color, vx, vxs, vy, gv) {
	this.scale = scale; // 縮尺
	this.dstWidth = dstWidth;
	this.dstHeight = dstHeight;
	this.kind = kind; // トランプの種類
	this.vx = vx; // X速度
	this.vxs = vxs; // 退場時の速度
	this.vy = vy; // Y速度
	this.gv = gv; // 重力
	this.position = { // 位置
		x: 0,
		y: 0
	};
};


■ 解説:メインのループ処理

ここはメインのループ処理です。

// ループ処理
function animloop(){
	requestAnimFrame(animloop);

	// カードの追加
	if(new Date() - startDate > interval){
		startDate = new Date();
		
		// 詳細値の作成
		kind = Math.random() * 10;
		scale = Math.random() * (0.25 - 0.1) + 0.1;
		dstWidth = imageWidth * scale;
		dstHeight = imageHeight * scale;
		x = Math.random() * (10) -5;
		xs = x / 10;
		y = Math.random()* 9 + 4;
		g = Math.random()* 0.2 + 0.3;
		indx = Cards.length;
		
		Cards[indx] = new Card(scale, kind, x, xs, -y, g);
		Cards[indx].position.x = Math.random() * (canvas.width);
		Cards[indx].position.y = 100;
	}
	
	// カードの更新
	for (var i in Cards) {
		Cards[i].update();
	}
}


この部分でクラス追加の制御をしてます。

// カードの追加
	if(new Date() - startDate > interval){
		startDate = new Date();</code>

今回はvar interval = 2000;に設定しているので2秒間隔ですね。


■ 解説:クラスの更新

Cards[i].update();で以下の処理を呼び出してます。

// 座標の更新
Card.prototype.update = function() {
	this.vy += this.gv;
	this.position.x += this.vx;
	this.position.y += this.vy;
	
	// 地面の衝突判定
	if (this.position.y > canvas.height - this.dstHeight) {
		this.vy *= -0.8;
		this.vx *= 0.85;
		this.position.y = canvas.height - this.dstHeight;
		if(Math.abs(this.vx) < 0.8){
			this.position.x += this.vxs;
		}
	}
	this.draw();
};

地面に衝突する(y座標がcanvasの大きさに達する)と、y軸の速度[vy]をマイナスにすることでトランプを上に描画しています。

x軸の速度が絶対値で0.8以下となった際は、これ以上バウンドしないと判断し、生成時の速度×0.1で等速に動かしています。


動かしてみた!

動かしてみると、こんな感じです!
youtu.be



ぜひ、以下リンクよりブラウザでお試しくださいね!
https://castoroides.github.io/others/Freecell_fall.html

ブラウザクラッシャーを作りたい!

ブラクラって知ってますか?

こんにちは、犬を飼いたい社内ニート Castoroides です!
結構有名なんですが、皆さんは「you are an idiot」ってご存じですか?

you are an idiot について

直訳すると「お前は馬鹿だ」です。
いわゆるジョークプログラムの一種ですが、置いてあるサイトはすでにリンク切れとなっているようです。

挙動は以下の通り。
www.youtube.com
「you are an idiot, hahahahahaha」と音を出しながら、ウィンドウが無限増殖していきます。
放っておくとブラウザおよびPCが負荷に耐えられず、ブルースクリーンが表示されてしまうといった挙動らしいです。
所詮はブラウザ内で動くプログラムなので危険性は低いです。
なぜならタスクマネージャーから強制終了できるから。


このようにブラウザを操作して、ユーザに嫌がらせをするプログラムをブラウザクラッシャー、略してブラクラと言ったりするんですが…


なんだかとっても楽しそうですよね?


と、いうわけでさっそく作っていきたいと思います!
コンセプトは「令和のブラクラ」!!!

念のため断っておきますが、上記で紹介した you are an idiot
これ普通にPCに悪影響ある可能性あるらしいのでお気を付けください。
(ウェブアーカイブ残っているぽいので念のため)


今回は安全性を意識した、全く悪意のないブラクラを作るつもりですので
ぜひ最後まで読んでいただければ幸いです!


令和式ブラクラを作成する

Step1 ブラクラ用Webページを作る

そこからかよって感じですが、
モチベに関わるのですごく大事なところです。

ということで、おしゃれなページつくるぞ~~!!!



(10分後)
f:id:castoroides_uky:20211009021603p:plain




1時間後…



(2時間後)できた!!!!!!!
https://castoroides.github.io/burakura/1_burakura_kari.html
f:id:castoroides_uky:20211009015816p:plain
なんということでしょう(匠)


素敵な?Webページが完成したので、これよりようやくプログラムを書いていきます。
ちなみにこのWebページには、すでに嫌がらせ要素を組み込んでいるのでクリックされる際はお気を付けください。


Step2 プログラムを組んでみる

先ほども書きましたが、以下のWebページには既に嫌がらせプログラムを設定しています。
https://castoroides.github.io/burakura/1_burakura_kari.html

内容はこんなの。

<script>
function buttonClick(){
  
  for(i=10; i>0; i--){
    alert("あと" + i + "回押してね(笑)");
  }
}
</script>

「クリック!」を押すとアラートが10回表示されるってだけ。
ここから嫌がらせの強度を上げていきたいと思います!



できました!

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>
<script>
const url = "https://castoroides.github.io/burakura/2_burakura_kari.html"

// ページが読みこまれた際に実行される、1フレーム(1/60秒)ごとに実行される関数
function draw() {
	//無限タブ増殖
	window.open(url, "_blank")
}
function buttonClick(){
	for(i=10; i>0; i--){
		alert("あと" + i + "回押してね(笑)");
	}
}
// Close字のメッセージ
window.onbeforeunload = function(e) {
	e.returnValue = "また来てね^^";
}
</script>

まずは1行目、
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"で、
フレーム処理を行うためのスクリプト「p5.js」を読み込んでます。

これは本来、アニメーションを組む際に利用するオープンソースライブラリです。これを読み込むことでfunction draw() が使えるようになります。


そしてブロック内のwindow.open(url, "_blank")であらかじめ設定していたURL(本コードでは自分自身)を呼び出して、新規ウィンドウとしてオープンしています。


最後のここで、ウィンドウクローズ時にポップアップを表示させるよう設定しています。
e.returnValue = "また来てね^^";でテキストを変更できるみたいですが2021年現在ではほとんどのブラウザで定型文が用意され、反映されないようになってるぽいです。

// Close字のメッセージ
window.onbeforeunload = function(e) {
	e.returnValue = "また来てね^^";
}</code>


Step3 さっそく動かしてみる

さっそくブラウザで動かしてみました!

…が、
f:id:castoroides_uky:20211009213301p:plain
ですよね~~~!!!!
流石ですchrome先輩!!!!!

我々がブラウザによって ”守られている存在” であることを再認識しつつ、
早々にブロックを解除します。

f:id:castoroides_uky:20211009222825p:plain

「完了」を押した途端、


f:id:castoroides_uky:20211009222930p:plain
うわぁ~~~~~~~~~!!!!!!!!!!
タブがものすごい勢いで錬成されていきます。

ちゃんとできてるみたいで安心です(最終的に重すぎてブラウザが落ちました)


しかし、このままでは真ん中のクリックボタンの存在意義がないので役割を持たせてあげようと思います。


できました、結構変わってます!

<script>
var dialog_list = ["ようこそ!", "これはブラウザクラッシャーです!","その後省略"];
function introduce(){
	for(i=0; i<10; i++){
		alert(dialog_list[i]);
	}
}
const url = "https://castoroides.github.io/burakura/3_burakura2021.html"
function buttonClick(){
	document.getElementById("change_txt").innerText = "頑張って閉じてね!!!!!";
	
	while(true){
		window.open(url, "_blank")//無限タブ増殖
		// 0.2秒待機
		var startDate = new Date();
		while (new Date() - startDate < 200);
	}
}
// Close字のメッセージ
window.onbeforeunload = function(e) {
	e.returnValue = "また来てね^^";
}
</script>

さっきのは開いた直後に無限フレーム処理をさせてましたが、ボタンクリックで無限ループに入るように変更しました。

あと、最悪の事態を回避できるようブロック内で0.2秒待機するようにしてます。
(待機なしで処理させた際、テストランでPCがなかなかしんどそうだったので…)

// 0.2秒待機
	var startDate = new Date();
	while (new Date() - startDate < 200);

new Dateで最新の時間が取得できるので、保存しといた時間と照合することで待機させています。

また、雑魚いブラクラの製作者のもとに警察からTELが来る事案もあるそうですので、説明ボタンを追加しています。

https://castoroides.github.io/burakura/3_burakura2021.html


動かしてみたらこんな感じ!
youtu.be

VBAで文字をフィーバーさせてみた

Excel VBAで意味わからんマクロ組んでみた

こんにちは、犬を飼いたい社内ニート Castoroides です!




はい。
今回はそういうことで、0.5秒ずつ文字色が変わっていくマクロを作成していきます。


Step1 Excelの購入

そこからかい!って感じですが…
だってライセンス料高いんだもん。

そのため個人のPCには一切Officeアプリ入れてません。
だってお家はOfficeじゃないし。
もちろん業務時間でおふざけマクロ組めるほど肝座っていません。

ということでさっそくAmazonへ!

やっぱり高い!

普段会社で使い倒しているからこそ高く感じてしまう、、、
Excelは人権にかかわるのでお値段何とかなりませんか?

インストール

こんばんは~^^

無事にインストール完了しました。
(クレカの請求が怖いですが…)


Step2 フィーバーさせる文字の用意

この文字列を1文ずつ分割してセルに入れていきます。
f:id:castoroides_uky:20211007193311p:plain

数式で分割するのがおすすめです。
=MID($A1,COLUMN()-1,1)
f:id:castoroides_uky:20211007193553p:plain

数式をコピーするとこんな感じ
f:id:castoroides_uky:20211007193917p:plain

いい感じ
f:id:castoroides_uky:20211007194026p:plain


Step3 マクロ作成

ここからが本番です!

まずは、いかなる時でも迅速に本マクロを実行できるよう、
個人用マクロブックに作成したいと思います。


「表示」→「再表示」→「PERSONAL.XLSB」を選択し、
「OK」を押して個人用マクロブックを開きます。
f:id:castoroides_uky:20211007195416p:plain


「開発」タブから「マクロ記録」
f:id:castoroides_uky:20211007195822p:plain


ショートカットもしっかり設定します。
(これでいつでも フィーバーできますね!)
f:id:castoroides_uky:20211007200102p:plain

あとは即「マクロの記録」を終了し、具体的な処理はVBで組んでいきます。
(もっといいやり方知ってたら教えてください)
f:id:castoroides_uky:20211007200433p:plain


コード(最終版)は以下の通り。

'買ったからには書かなくちゃ

Const col_max As Integer = 200 '書式の上限
Dim i As Integer
Dim rng, c As Range
Dim col_list() As Variant
'キー入力取得のおまじない
Private Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long

Sub fever_string()
'
' fever_string Macro
' Let's Fever!!!!!
'
' Keyboard Shortcut: Ctrl+Shift+F
'
    MsgBox "Let's Fever!!!!!    " & vbCrLf & "(EnterキーでStop)    "

    init_color '文字色の作成
    
    Dim t_cnt As Long: t_cnt = 0
    Do While t_cnt < 1000
        Application.Wait [Now()] + 500 / 86400000
        t_cnt = t_cnt + 1
        
        change_color '文字色の変更
        
        'Enter入力で停止
        If GetAsyncKeyState(vbKeyReturn) Then
            Exit Sub
        End If
    Loop
End Sub

Sub init_color() '書式の制限回避
    Dim col_1, col_2, col_3 As Integer
    For i = 0 To col_max
        'Int(Rnd() * (最大値 - 最小値 + 1) + 最小値)
        col_1 = Int(Rnd() * 256)
        col_2 = Int(Rnd() * 256)
        col_3 = Int(Rnd() * 256)
        
        ReDim Preserve col_list(i)
        col_list(i) = RGB(col_1, col_2, col_3)
    Next i
End Sub

Sub change_color()
    'Set rng = Selection 'アクティブセルの場合
    Set rng = Range("A1", "AC20") 'ここを毎回指定
    
    For Each c In rng
        i = Int(Rnd() * col_max + 1)
        c.Cells.Font.Color = col_list(i)
    Next c
End Sub


init_color()であらかじめ文字色を規定数作成しています。
これはExcelでは1ブックあたりの書式の上限数が決まっているからです。

不親切でおなじみの公式サポートページでは以下のように書かれています。

固有のフォントの種類
1,024 個のグローバル フォントを使用可能 (ブックあたり 512 個)

support.microsoft.com


文字色は512種類が限界みたいですね(おそらく)
このマクロは実行毎に200色ランダム生成するので3回目で以下のエラーが出ます🤦‍♂️
f:id:castoroides_uky:20211007204819p:plain

その際は一度ブックを閉じないとフィーバーできないんですよね…。
Const col_max As Integer = 200200を減らせばいい話ですが。


文字色を生成した後はApplication.Wait [Now()] + 500 / 86400000
0.5秒ずつ時間を止めつつchange_color()でセルごとに色を変更しています。

86400000は1日を秒換算した値みたいですね。なるほど😙


動かすとこんな感じ!
youtu.be

はてなブログ、始めました

初投稿!

初めまして、犬を飼いたい社内ニート Castoroides です!
このブログでは、私が作ったクソコードをご紹介したいと思ってます。

もともとWixでちびちび書いてたんですが、はてなのほうが自由度高そうだったので。

とりあえず「はてな記法」でHello Worldでもしておきますね。

ソース

<code>Hello World!</code>

Hello World!


以上、よろしくお願いします!

人生で初めて作ったプログラム

初めて書いたプログラムを覚えていますか?

こんにちは、犬を飼いたい社内ニート Castoroides です!

皆さんは人生で初めて作成したコードがどんなのか、覚えていますか?
私はしっかり覚えていますよ。

そもそもプログラムを始めたきっかけは、大学の授業で面白かったからです。
初めて「Hello World」したときは、とても感動したのをよく覚えています。

准教「print "Hello World"って打ってみなよ」

私「ほぉ」

私「指一本カチカチ…」

私「!!!!!」

准教「^^」

わかんないけどすごいことが起きた!


当時は舞い上がったものです…。(たかだか2年前のことですが)
そして調子に乗った私は独学でPythonを学び、クソコードを生成するようになったのでした。

今回は、件の授業で「こんな簡単にコーディングってできるんだ!」と思い大学生時代に初めて自分で考えて作ったクソコードをお披露目いたします!


初めて私が作ったクソコード、それは…

犬変換プログラム🐕

f:id:castoroides_uky:20211006221425p:plain
犬変換.py
# 入力した文字をすべて犬に変換する関数を作る
print("入力した文字が全て犬に変換されます。")

# 関数を定義
def dog(tmp):
	lis = [tm for tm in tmp]
	num = len( lis)
	return ("犬" * num)

# 引数を犬に変換する
td = dog (str(input("なにか入力してください: ")))
print("\n" + td + "\n")

tmp = str(input("Enterで終了"))

透けて見えるクソ感

読めばわかる通り、inputで入力された文字列をPythonの内包表記で1文字ずつ取り出しリスト化。
その後リストの長さをlenで取得し、その長さの分だけ「犬」を出力。

わざわざリスト化しなくても
return ("犬" * len(tmp))でいいじゃんとか、
そもそも関数にするほどの処理じゃねーだろとか、

ツッコミたいことは多々ある🤦‍♂️
でもこれ、初めて作ったやつですからね!

自分の中ではお気に入りのプログラムなのでJavascriptで書き直してみました。

犬変換プログラム(JavaScript
何か入力してください:



ちなみにこのプログラム、就活で提出したら内定出ました。
ホントです。

!