🦖
🦕
🦖
🦕
🦖
🦕
🦖
🦕
🦖
🦕

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

最近、アビスリウムにハマりました。

スマホゲームです。

apps.apple.com

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


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


このゲーム、イベント時はタップするのがめんどくさいです。なのでNoxplayerを使ってタップを自動化したいと思います。
※イベント時:2秒に1回程度 魚がアイテムを吐くので、それをタップして回収しなければならない。

NoxPlayer

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

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

NoxPlayerはマクロを組むことができます。つまり単純操作の自動化が可能になっています。
ちなみに、「スクリプト」という機能でExcelのマクロのように操作を記録することもできます。(中華ゲームとかでやるとチート扱いされてBANされるかもです)


NoxPlayerのマクロによるタップ自動化

仮想キーの作成

まず、Noxplayerでアビスリウムを開きます。

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

「マクロ」をクリックします。

ここで作成された円をクリックすることでマクロが起動します。そのため、画面の端っこに置いておくのが良いです。

円をクリックしなくてもマクロを実行させるショートカットキーを設定できます。今回はCtrl+Aに設定してみました。


マクロの設定

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

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

色んなことができそうなパーツが揃っています。(今回は「クリック」と「ループ」以外は使いませんが)

要するに、今回組んだのはイベントアイテムやその他時間経過により出現するアイテムが取得できるよう「画面全体をまんべんなくタップさせる」というマクロです。

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

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



タップゲーを自動化するとつまらなくなりました。

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

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

子供のころ、PCのフリーセルピンボールが大好きでした。
フリーセルは最後にシャーッてなるのがいいんですよね。あのシャーッてやつをJavascriptで再現していきます。


ちなみに昔と違って、今のWindowsはストアからフリーセルをインストールする必要があるみたいですね。
www.microsoft.com



今でもシャーやってくれるみたいです。


と、思ったら別のアニメーションも用意されてました。



このアニメーションをJSで組んでみる

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



2日後


微調整こだわり過ぎて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

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

有名ブラクラ、「you are an idiot」を拝見して面白かったので似たものを作ってみました。

you are an idiot について

ジョークプログラムの一種ですが、置いてあるサイトはすでにリンク切れとなっているようです。

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


このようにブラウザを操作してユーザに嫌がらせをするサイトをブラウザクラッシャー、略してブラクラといいます。
ちなみに、少し前に高校生が遊びで作って「警察から連絡来た」みたいな事案あったらしいので、くれぐれもガチで組んではいけません。



Webページを作る

HTML苦手ですが頑張っていきます。

https://castoroides.github.io/burakura/1_burakura_kari.html

自信作です。



プログラムを組んでみる

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>


さっそく動かしてみる

さっそくブラウザで動かしてみます。

…が、

chromeにブロックされてしまいました。ちゃんとしてますねクロームは。

テストしたいのでブロックを解除します。

「完了」を押した途端、


タブがものすごい勢いで錬成されていきます。

ちゃんと処理が重すぎてブラウザが落ちてくれました、よかったです。



さらにコードを見直して、最終版は以下のようにしてみました。

<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>


ボタンクリックで無限ループに入るように変更しました。
またテストランで趣味PCがかわいそうだったので、タブ生成の間隔を0.2秒空けました。

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

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

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


無限タブ増殖の様子は以下の通りです。
youtu.be

Excel VBAで0.5秒ずつ文字色が変わっていくマクロ組んでみた

久しぶりにエクセルでVBA扱いたくなってこの記事書いてます。
そういうことなので、0.5秒ずつ文字色が変わっていくマクロを作成していきます。


ステップ1:Excelの購入

衝動的にVBA触りたくなったので、まずはライセンスを購入します。
Officeアプリはもはや高級品だと思ってます。


アマゾンへ向かう


インストール

インストール完了です。


ステップ2:文字を打ち込む(読まなくていいです)

この文字列を1文ずつ分割してセルに入れていきます。

数式で分割します。
=MID($A1,COLUMN()-1,1)

数式をコピーするとこんな感じ。

いい感じです。


ステップ3:マクロ作成

ここからが本番です。

まずは個人用マクロブックをエクセル君に生成してもらおうと思います。


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


「開発」タブから「マクロ記録」


ショートカットも一応設定しておきます。

あとは即「マクロの記録」を終了し、具体的な処理はVBで組んでいきます。
(もっといいやり方ありそう)


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

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回目で以下のエラーが出てしまいます。

エラーが出たら一度ブックを閉じて使用文字色のリセットをします。
文字色の候補を減らせばいいだけですがめんどくさいのでこのままで行きます。


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

86400000は1日を秒換算した値みたいですね。


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

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

人生で初めて作成したプログラムのこと、覚えていますか?
私はしっかり覚えています。以下となりますご査収ください。


犬変換プログラム(Python

犬変換.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
何か入力してください:



以下Javascriptでのソース

<form>
何か入力してください:
<textarea rows="2" cols="40" id="tarea"></textarea>
<input type="button" value="変換" onclick="func()">
</form>
<script>
let func = (button) => {
	let element = document.getElementById('tarea');
	element.value = '犬'.repeat(element.value.length); 
}
</script>


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