クソアプリでクソカードにクソロックがかかってクソサポートにたらいまわしにされた話

はいクソー

こんにちは。100年ぶりの記事はタイトル通りクソまみれです。
コンプラに配慮して固有名詞は出しません。紳士ですから。


先日、クソアプリでいつも通り入金しようとしたところ、
「クレジットカードの認証に失敗しました。会員情報にご登録いただいているクレジットカード会社にお問い合わせください。(2330)」
と表示されました。
当然、暗証番号などのロックはかかっていません。

エラーコードをググった結果、カード会社様にあやしいと判断されて勝手にロックされたようです。
普通に入金しただけなんですが、AIと将軍様が言う事は絶対ですからね。たのしー
で、解除して欲しければサポセンに電話しろと。

指示通りdカードコンプラに配慮して頭文字)のサポセンに電話したところ
「アプリ側のエラーだからそっちに聞いて!」とのこと。
またまたご冗談を・・・

仕方なく指示通りJR(コンプラに配慮して頭文字)のサポセンに電話したところ
「カード側のエラーだからそっちに聞いて!」とのこと。
で、でたーーーwwwたらいまわしされるやつーーーwww

まあカード側が原因だと思ってたので
再度dカードコンプラに配慮して頭文字)のサポセンに電話したところ
「ロックされてるから解除しとくね!」とのこと。
わけわかんないや!!!


というわけで、dカードコンプラに配慮して頭文字)の特徴。
・AIの気分次第でカードがロックされる
・サポセンの気分次第で回答が変わる
すっごーい!!!

Androidアプリ開発未経験の初心者が SQLiteのDBをAndroid StudioでListViewしてみた

パソコンで作ったDBをAndroidアプリに表示したかっただけなのですが、
基礎をわかってる人向けのサンプルコードしか見つからなかったので、
初心者(自分)向けにコメントを書きまくったコードを残しておきます。
(いきなり「R」とか言われても「なんのこっちゃ」って感じだったので。。)

なんかヘルパーとかカーソルとかアダプタとかを、ごにょごにょやるようです。


仕様
 ・表示するDBは、PCで作ったSQLiteのDB
 ・DBに含まれる dabimas テーブルの No 列と 種牡馬名 列を表示
 ・表示レイアウトは android.R.layout.simple_list_item_2


MainActivity.java

package com.example.testapp001;

import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends AppCompatActivity {   // Empty Activityを選択するとデフォルトで生成される

  private ListView myListView;                          // 画面に表示するListViewのオブジェクト

  @Override                                             // お約束: ActivityクラスのonCreateメソッドを上書きします宣言
  protected void onCreate(Bundle savedInstanceState) {  // お約束: onCreateはプロセス起動(Create)時の最初の処理
    super.onCreate(savedInstanceState);                 // お約束
    setContentView(R.layout.activity_main);             // お約束: activity_main.xmlの画面配置を渡す

    //DB読み出し
    TestOpenHelper mDbHelper = new TestOpenHelper(this);    // DBのヘルパーを生成 (TestOpenHelper.java参照)
    SQLiteDatabase db = mDbHelper.getWritableDatabase();    // ヘルパーから読み出すDBを取得
    Cursor c = db.rawQuery(
                "SELECT No as _id, 種牡馬名 FROM dabimas;", // SQL文でカーソルを取得 (SQL文: dabimasテーブルから「No」と「種牡馬名」を取得)
                null);                                      // [注意] SimpleCursorAdapterの仕様で「_id」というcolumnを含まなければならないッ!

    //adapter生成
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(
        this,                                               // コンテキスト: お約束
        android.R.layout.simple_list_item_2,                // レイアウト: android標準のテキストを2行表示するレイアウト
        c,                                                  // カーソル: SQLiteのカーソル
        new String[] {"_id", "種牡馬名"},                   // 表示元: SQLiteのcolumn名
        new int[] {android.R.id.text1, android.R.id.text2}, // 表示先: simple_list_item_2のtext1とtext2
        0);                                                 // 謎のflag: お約束

    //ListViewで表示
    myListView = (ListView)findViewById(R.id.list_view);    //activity_main.xmlのlist_viewでオブジェクト生成
    myListView.setAdapter(adapter);                         //生成したオブジェクトにアダプタをセット
  }
}

TestOpenHelper.java

package com.example.testapp001;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TestOpenHelper extends SQLiteOpenHelper {

  private static final String SRC_DB = "TestDB.db"; // コピー元: assetsフォルダ(AndroidStudioProjects\ProjectName\app\src\main\assets)のdbファイル
  private static final String APP_DB = "TestDB";    // コピー先: アプリ内部のdb
  private static final int DB_VERSION = 1;

  private Context context;
  private File dbPath;
  private boolean createDatabase = false;

  public TestOpenHelper(Context context) {
    super(context, APP_DB, null, DB_VERSION);
    this.context = context;                         // 変数に保存
    this.dbPath = context.getDatabasePath(APP_DB);  // 変数に保存
    context.deleteDatabase(APP_DB);                 // 一度APP_DBを作るとアプリ内に残ってしまうので毎回削除(デバッグ用)
  }

  @Override
  public synchronized SQLiteDatabase getWritableDatabase() {  //Main側プログラムから呼ばれるメソッド
    SQLiteDatabase database = super.getWritableDatabase();
    if (createDatabase) {                                     //onCreateがコールされた(=APP_DBが無い)場合
      try {
        database = copyDatabase(database);                    //SRC_DB_NAMEからAPP_DBへコピー
      } catch (IOException e) {
      }
    }
    return database;                                          //APP_DBを返す
  }

  private SQLiteDatabase copyDatabase(SQLiteDatabase database) throws IOException {
    database.close();                                         // 書き換えできるようにdbを閉じる

    InputStream input = context.getAssets().open(SRC_DB);     // assetsフォルダのdbファイル
    OutputStream output = new FileOutputStream(this.dbPath);  // APP_DBのdbファイル
    copy(input, output);                                      // コピー処理

    createDatabase = false;                                   // DB作成フラグOFF
    return super.getWritableDatabase();                       // dbを再度開く
  }

  @Override
  public void onCreate(SQLiteDatabase db) { // APP_DBが無い状態でgetWritableDatabaseがコールされるとここに来る
    super.onOpen(db);                       // これいる??
    this.createDatabase = true;             // DB作成フラグON
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  // DB_VERSIONが上がった時はここに来る
    onUpgrade(db, oldVersion, newVersion);  // これいる??
  }

  // CopyUtilsからのコピペ
  private static int copy(InputStream input, OutputStream output) throws IOException {
    byte[] buffer = new byte[1024 * 4];
    int count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
      output.write(buffer, 0, n);
      count += n;
    }
    return count;
  }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <ListView
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

error C2871: 'std' : この名前を指定された名前空間は存在しません。

このエラーで検索しても期待した回答が得られず、ドッタンバッタン大騒ぎしている人向けにメモ書きを残しときます。ポンコツ記事なのでたぶん役に立ちません。

[環境]
VC++ (C++/CLI)
 
[エラーになったコード]
using namespace std;
std::string str;
 
[解決策]
#include <string>  ←追加 (※string.hではない)
using namespace std;
std::string str;

大半のかしこいフレンズから「は?」という声が聞こえて来そうだが、「よくわかんないけど動けばいいや!」というSE(サーバルエンジニア)は案外こういうのでハマる。(と思う)
持ち前のジャンプ力で、C言語からC++/CLIに3段くらい上ってしまった場合は特に危険。

これはコンパイラが「std」ではなく「std::string」の方を指してくくれば、サーバルエンジニアでも「たぶん#includeが無いんだね!」と推測できそうだが、さすがにそこまでナビゲートできないのが案内ロボットの限界である。

そもそもこういう勘違いが起こるのは、VC++でフォームアプリ等を作ると#includeを書かなくてもSystem名前空間が宣言できてしまうのが原因の1つだと思う。

using namespace System;  ←これは正常

System名前空間が宣言できるのだから、C++標準のstd名前空間は当然書けると思ってしまい・・・

using namespace std;   ←これはエラーになる

「あれ?Systemが書けるのにstdが書けないよ?・・・あ、そっかー!C++C++/CLIって全然違うみたいだし、C++/CLIにはstd名前空間が存在しないんだね!」
と、どんどん違う方向に突っ走ってしまいかねない。

そのようなサーバルエンジニアを、このポンコツ記事で1人でも救う事ができれば本望である。
のけものはいないのだから。

[解説]
 
#include <string.h>
→標準関数などが定義されている。
 
#include <string>
→「std名前空間」と「std名前空間内の関数」などが定義されている。
 
なお同じ名前空間は2回以上出現しても問題ない。
例えば次のコードを書くと、Japari名前空間内にidol関数とboss関数が作成される。
 
namespace Japari{
  char* idol(void){
    return "ペパプ";
  }
}
namespace Japari{
  char* boss(char* name){
    if(!strcmp(name, "カバン")) return "ヤア、カバン";
    else           return "検索中・・・";
  }
}

エアプによる覚醒パンドラの火力に関する考察

覚醒パンドラって強いらしいけど、8個消しだし不知火型だしいまいちわからん!
というわけで、覚醒パンドラの火力についてエアプで検証したいと思います。

比較対象

比較的似た性能を持つ覚醒堕ルシと比較します。

はじめに

LSの全パラメータ上昇(1.25倍)の恩恵で、6個消し14倍・8個消し25倍になります。
(比較対象の堕ルシの倍率については、当ブログの過去のエントリーを参照)

パーティー前提条件

総攻撃力を10000、覚醒スキルを次のように仮定します。

  • 属性強化:12個

以降、消したドロップはすべて「ドロップ強化なし」とみなします。

1列消し

次の条件で5コンボした場合の火力はこんな感じ。
(ダメージ計算は ここ を使用。小数点以下は四捨五入)
(上記サイトの都合上、9個消しで計算)
 ・ ダルシ      6個  16×(8) = 128万
 ・ ダルシ      9個  16×(11) = 176万
 ・ ダルシ(神キラー) 6個  16×(8)×(5/3) = 213万
 ・ ダルシ(神キラー) 9個  16×(11)×(5/3) = 293万
 ・ パンドラ     6個  14×(8) = 112万
 ・ パンドラ     9個  25×(11) = 275万

2列消し

次の条件で5コンボした場合の火力はこんな感じ。
 ・ ダルシ      6+6  16×(12+12) = 384万
 ・ ダルシ      9+6  16×(17+12) = 464万
 ・ ダルシ(神キラー) 6+6  16×(12+12)×(5/3) = 640万
 ・ ダルシ(神キラー) 9+6  16×(17+12)×(5/3) = 773万
 ・ パンドラ     6+6  14×(12+12) = 336万
 ・ パンドラ     9+6  25×(17+12) = 725万

サブに堕ルシを入れた場合

次の条件で5コンボした場合の火力はこんな感じ。
 ・ パンドラ(神キラー) 6+6  14×(12+12)×(4/3) = 448万
 ・ パンドラ(神キラー) 9+6  25×(17+12)×(4/3) = 966万

で、結局どうなのよ?

6個消しでも堕ルシ並の火力が出ますが、相手が神タイプの場合は8個消しでやっと堕ルシに追いつく感じです。
サブに堕ルシを1体入れれば、相手が神タイプであっても8個消しでLF堕ルシを上回りますが、6個消しだと明らかに劣ります。
けっこう性能は拮抗しており、開発側は上手い調整をしたのではないでしょうか。
なお、泥強覚醒を5個詰めば単純計算で火力が1.5倍程度になるため、並のボスであれば9+6でワンパンできるはずです。

エアプによる覚醒堕ルシの覚醒スキルに関する考察

覚醒堕ルシって強いらしいけど、6個消しで9倍だしいまいちわからん!
というわけで、覚醒堕ルシの覚醒スキルについてエアプで検証したいと思います。

はじめに

LSの全パラメータ上昇(1.35倍)の恩恵で、攻撃倍率は実質16倍になります。
ダメージ計算は ここ を使用。小数点以下は四捨五入。

前提条件

パーティー総攻撃力を10000と仮定します。

泥強マシマシ

  • 属性強化:0個
  • ドロップ強化覚醒:12個

この条件で、5コンボした場合の火力はこんな感じ。
※消したドロップはすべて「強化ドロップ」と仮定
※()内は神キラー発動時

  • 6個消し 16×(8) = 128万 (213万)
  • 6+6   16×(8+8) = 256万 (426万)
  • 6+6+6  16×(8+8+8) = 384万 (640万)

列強マシマシ

  • 属性強化:12個
  • ドロップ強化覚醒:0個

この条件で、5コンボした場合の火力はこんな感じ。
※消したドロップはすべて「通常ドロップ(強化なし)」と仮定
※()内は神キラー発動時

  • 6個消し 16×(8) = 128万 (213万)
  • 6+6   16×(12+12) = 384万 (640万)
  • 6+6+6  16×(16+16+16) = 768万 (1280万)

ハイブリッド

  • 属性強化:8個
  • ドロップ強化覚醒:4個

この条件で、5コンボした場合の火力はこんな感じ。
※消したドロップはすべて「強化ドロップ」と仮定
※()内は神キラー発動時

  • 6個消し 16×(10) = 160万 (266万)
  • 6+6   16×(15+15) = 480万 (800万)
  • 6+6+6  16×(19+19+19) = 912万 (1520万)

で、結局どうなのよ?

覚醒スキルの優先順位は「盤面を強化ドロップにするためのドロップ強化 > 属性強化 > ダメージ強化のためのドロップ強化」にすべきです。
これはダルシに限った事ではありません。

あとがき

今回これを検証した理由は、前回のエントリー(エアプによる覚醒堕ルシの火力に関する考察 - くらびし!)でハイブリッドを前提条件としたので、ドロップ強化覚醒を入れずに「書いてある数値より火力が出ない!」という人がいるのではないかと思ったためです。(今思うと前提条件からドロップ強化覚醒を外すべきだったかもしれません。なんなすみません)

エアプによる覚醒堕ルシの火力に関する考察

覚醒堕ダルシって強いらしいけど、6個消しで9倍だしいまいちわからん!
というわけで、覚醒堕ルシの火力についてエアプで検証したいと思います。

はじめに

LSの全パラメータ上昇(1.35倍)の恩恵で、攻撃倍率は実質16倍になります。

比較対象

単色・列主体なので、シヴァドラと比較します。

パーティー前提条件

総攻撃力を10000、覚醒スキルを次のように仮定します。

  • ドロップ強化:4個
  • 属性強化:12個

以降、消したドロップはすべて強化ドロップとみなします。

6個消しの威力 (神キラー発動なし)

次の条件で5コンボした場合の火力はこんな感じ。
(ダメージ計算は ここ を使用。小数点以下は四捨五入)
 ・ シヴァドラ 6   25×(13) = 325万
 ・ シヴァドラ 6+6  25×(19+19) = 950万
 ・ シヴァドラ 6+6+6 25×(26+26+26) = 1950万

 ・ ダルシ   6   16×(13) = 208万
 ・ ダルシ   6+6  16×(19+19) = 608万
 ・ ダルシ   6+6+6 16×(26+26+26) = 1248万

6個消しの威力 (神キラー発動あり)

カビキラーを発動し、5コンボした場合の火力はこんな感じ。
 ・ ダルシ   6   16×(13)×(5/3) = 347万
 ・ ダルシ   6+6  16×(19+19)×(5/3) = 1013万
 ・ ダルシ   6+6+6 16×(26+26+26)×(5/3) = 2080万

キラー系は単体の攻撃力が3倍なので、全員の攻撃力が同じだと仮定すると、全体として(1/3)倍の底上げになります。LFダルシの場合、(2/3)倍の底上げになります。

で、結局どうなのよ?

LFダルシで神キラーを発動すると、全体としてシヴァドラ並の火力が出るようです。
神キラーを発動しなくても2列で600万なので、耐久力を考えれば十分。
ただし、闇半減かつ神でない場合は急に火力が落ちるため、うっかり発狂ゾーンに入らないよう注意する必要がありそうです。

エアプによるヨミドラの覚醒スキルに関する考察

ヨミドラって強いらしいけど、5個消しだしいまいちわからん!
というわけで、ヨミドラの覚醒スキルについてエアプで検証したいと思います。

前提条件

パーティー総攻撃力を10000、消したドロップはすべて強化ドロップとみなします。

2wayマシマシ

  • ドロップ強化覚醒:4個
  • 2way:12個
  • 属性強化:0個

この条件で、5コンボした場合の火力はこんな感じ。
(ダメージ計算は ここ を使用。小数点以下は四捨五入)

  • 5個消し 36×(5)   = 180万
  • 5+4   36×(5+8)  = 468万
  • 5+4+4  36×(5+8+8) = 756万

道中なら4個消し1セット、降臨ボスなら4個消し2セットで突破できそう。

列強マシマシ

  • ドロップ強化覚醒:4個
  • 2way:0個
  • 属性強化:12個

この条件で、5コンボした場合の火力はこんな感じ。

  • 5個消し 36×(5)    = 180万
  • 5+6   36×(10+13)  = 828万
  • 5+6+3  36×(10+13+6) = 1044万

1列消せば並のボスはワンパンできそう。

泥強マシマシ

  • ドロップ強化覚醒:16個
  • 2way:0個
  • 属性強化:0個

この条件で、5コンボした場合の火力はこんな感じ。

  • 5個消し 36×(7)   = 252万 (にっこにー)
  • 5+4   36×(7+6)  = 468万
  • 5+4+4  36×(7+6+6) = 684万
  • 5+6   36×(7+9)  = 576万
  • 5+6+3  36×(7+9+4) = 720万

2wayも列も無い割には、結構な火力が出るようです。

で、結局どうなのよ?

どれをトッピングしてもあまり大差なし、だと思います。
火力は列強が優勢ですが、必要なドロップやコンボのしやすさを考えると、泥強や2wayの方が良いかもしれません。
せっかくなので泥強マシマシにしてドヤ顔するのはどうでしょう。ネフたそかわいい