goo blog サービス終了のお知らせ 

CyberChaos(さいばかおす)

プログラミング言語、トランスパイラ、RPA、ChatGPT、データマイニング、リバースエンジニアリングのための忘備録

AutoCADでテトリス!C#版www

2025-04-05 22:10:29 | Visual C#
// AutoCAD用テトリスゲーム (C#)
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Threading;

[assembly: CommandClass(typeof(TetrisGame.TetrisCommands))]

namespace TetrisGame
{
public class TetrisCommands
{
private static bool gameOver = false;
private static int score = 0;
private static int[,] grid;
private static List<int[,]> currentShape;
private static int currentRotation = 0;
private static int shapeX = 0;
private static int shapeY = 0;
private static readonly int gridWidth = 10;
private static readonly int gridHeight = 20;
private static readonly int blockSize = 20;
private static readonly int startX = 100;
private static readonly int startY = 100;
private static List<List<int[,]>> shapes;
private static Database db;
private static Editor ed;

[CommandMethod("TETRIS")]
public void Tetris()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
db = doc.Database;
ed = doc.Editor;

try
{
InitializeGame();
DrawGrid();
SpawnNewShape();
DrawShape();

// ゲームループを別スレッドで実行
Thread gameThread = new Thread(GameLoop);
gameThread.Start();

// キーハンドリング
while (!gameOver)
{
PromptResult result = ed.GetKeywords("\n[← Left][→ Right][↓ Down][↑ Rotate][Space Drop]");
if (result.Status == PromptStatus.OK)
{
HandleInput(result.StringResult);
DrawShape();
}
}

ed.WriteMessage("\nGame Over! Final Score: " + score);
}
catch (System.Exception ex)
{
ed.WriteMessage("\nError: " + ex.Message);
}
}

private void InitializeGame()
{
gameOver = false;
score = 0;
grid = new int[gridWidth, gridHeight];
shapes = new List<List<int[,]>>();

// テトリミノの形状定義
// I
shapes.Add(new List<int[,]> {
new int[4,2] { {0,0}, {1,0}, {2,0}, {3,0} },
new int[4,2] { {0,0}, {0,1}, {0,2}, {0,3} }
});

// O
shapes.Add(new List<int[,]> {
new int[4,2] { {0,0}, {1,0}, {0,1}, {1,1} }
});

// T
shapes.Add(new List<int[,]> {
new int[4,2] { {0,0}, {1,0}, {2,0}, {1,1} },
new int[4,2] { {1,0}, {1,1}, {1,2}, {0,1} },
new int[4,2] { {0,1}, {1,1}, {2,1}, {1,0} },
new int[4,2] { {1,0}, {1,1}, {1,2}, {2,1} }
});

// 他の形状も同様に定義...
}

private void SpawnNewShape()
{
Random rand = new Random();
currentShape = shapes[rand.Next(shapes.Count)];
currentRotation = 0;
shapeX = gridWidth / 2;
shapeY = 0;

if (CheckCollision())
{
gameOver = true;
}
}

private bool CheckCollision()
{
int[,] shape = currentShape[currentRotation];
for (int i = 0; i
{
int x = shapeX + shape[i, 0];
int y = shapeY + shape[i, 1];

if (x < 0 || x >= gridWidth || y >= gridHeight || (y >= 0 && grid[x, y] != 0))
{
return true;
}
}
return false;
}

private void LockShape()
{
int[,] shape = currentShape[currentRotation];
for (int i = 0; i
{
int x = shapeX + shape[i, 0];
int y = shapeY + shape[i, 1];
if (y >= 0)
{
grid[x, y] = 1;
}
}

// ライン消去チェック
int linesCleared = 0;
for (int y = gridHeight - 1; y >= 0; y--)
{
bool lineFull = true;
for (int x = 0; x
{
if (grid[x, y] == 0)
{
lineFull = false;
break;
}
}

if (lineFull)
{
linesCleared++;
// ラインを消して上を下にずらす
for (int y2 = y; y2 > 0; y2--)
{
for (int x = 0; x
{
grid[x, y2] = grid[x, y2 - 1];
}
}
// 最上部をクリア
for (int x = 0; x
{
grid[x, 0] = 0;
}
y++; // 同じ行をもう一度チェック
}
}

// スコア更新
score += linesCleared * linesCleared * 100;
}

private void DrawGrid()
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

// グリッドを描画
for (int x = 0; x <= gridWidth; x++)
{
Line line = new Line(
new Point3d(startX + x * blockSize, startY, 0),
new Point3d(startX + x * blockSize, startY + gridHeight * blockSize, 0));
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
}

for (int y = 0; y <= gridHeight; y++)
{
Line line = new Line(
new Point3d(startX, startY + y * blockSize, 0),
new Point3d(startX + gridWidth * blockSize, startY + y * blockSize, 0));
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
}

tr.Commit();
}
}

private void DrawShape()
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

// 既存の形状を削除
foreach (ObjectId id in btr)
{
DBObject obj = tr.GetObject(id, OpenMode.ForRead);
if (obj is Solid && obj.Layer == "TETRIS")
{
obj.UpgradeOpen();
obj.Erase();
}
}

// 現在の形状を描画
int[,] shape = currentShape[currentRotation];
for (int i = 0; i
{
int x = shapeX + shape[i, 0];
int y = shapeY + shape[i, 1];

if (y >= 0)
{
Solid box = new Solid(
new Point3d(startX + x * blockSize, startY + y * blockSize, 0),
new Point3d(startX + (x + 1) * blockSize, startY + y * blockSize, 0),
new Point3d(startX + x * blockSize, startY + (y + 1) * blockSize, 0),
new Point3d(startX + (x + 1) * blockSize, startY + (y + 1) * blockSize, 0));
box.Layer = "TETRIS";
box.ColorIndex = 1; // Red
btr.AppendEntity(box);
tr.AddNewlyCreatedDBObject(box, true);
}
}

// 固定されたブロックを描画
for (int x = 0; x
{
for (int y = 0; y
{
if (grid[x, y] != 0)
{
Solid box = new Solid(
new Point3d(startX + x * blockSize, startY + y * blockSize, 0),
new Point3d(startX + (x + 1) * blockSize, startY + y * blockSize, 0),
new Point3d(startX + x * blockSize, startY + (y + 1) * blockSize, 0),
new Point3d(startX + (x + 1) * blockSize, startY + (y + 1) * blockSize, 0));
box.Layer = "TETRIS";
box.ColorIndex = 3; // Green
btr.AppendEntity(box);
tr.AddNewlyCreatedDBObject(box, true);
}
}
}

tr.Commit();
}
}

private void HandleInput(string input)
{
switch (input)
{
case "Left":
shapeX--;
if (CheckCollision()) shapeX++;
break;
case "Right":
shapeX++;
if (CheckCollision()) shapeX--;
break;
case "Down":
shapeY++;
if (CheckCollision()) shapeY--;
break;
case "Up":
currentRotation = (currentRotation + 1) % currentShape.Count;
if (CheckCollision()) currentRotation = (currentRotation - 1 + currentShape.Count) % currentShape.Count;
break;
case "Space":
while (!CheckCollision())
{
shapeY++;
}
shapeY--;
break;
}
}

private void GameLoop()
{
while (!gameOver)
{
Thread.Sleep(500); // 0.5秒ごとに更新

shapeY++;
if (CheckCollision())
{
shapeY--;
LockShape();
SpawnNewShape();
}

DrawShape();
ed.WriteMessage("\nScore: " + score);
}
}
}
}


**C#版**:
- Visual Studioで.NETプロジェクトを作成し、AutoCAD .NET APIを参照に追加
- コードをコンパイルしてDLLを作成
- AutoCADで「NETLOAD」コマンドでDLLをロード
- コマンドラインで「TETRIS」と入力して実行

## 操作方法
- 左右矢印キー: 左右移動
- 下矢印キー: 加速落下
- 上矢印キー: 回転
- スペースキー: 即時落下

C#を使いCATIAで任意の直線を描く方法

2025-03-15 06:27:34 | Visual C#
C#でCATIAを操作する場合、CATIAの **Automation API**(COMベース)を使用します。C#はCOMとの連携が非常に簡単で、CATIAの操作に適しています。以下に、C#でCATIAを操作し、ユーザーから座標を入力させて直線を描画する方法を説明します。

---

### C#でCATIAを操作する手順

1. **CATIAのAutomation APIを使用する準備**
- CATIAのAutomation APIはCOMベースで提供されています。
- C#では、COMオブジェクトを簡単に操作できます。

2. **CATIAのタイプライブラリを参照に追加**
- Visual StudioでCATIAのタイプライブラリを参照に追加します。

3. **CATIAのインスタンスを作成**
- CATIAアプリケーションのインスタンスを作成し、ドキュメントやパートを操作します。

4. **直線を描く**
- ユーザーから座標を入力させ、指定された座標に基づいて直線を描画します。

---

### サンプルプログラム

以下は、C#でCATIAを操作し、ユーザーから座標を入力させて直線を描画するプログラムの例です。

```csharp
using System;
using CATIA;

namespace CATIA_LineDrawing
{
class Program
{
static void Main(string[] args)
{
try
{
// CATIAアプリケーションのインスタンスを作成
Application catia = (Application)Activator.CreateInstance(Type.GetTypeFromProgID("CATIA.Application"));
if (catia == null)
{
Console.WriteLine("CATIAアプリケーションの起動に失敗しました。");
return;
}

// CATIAを表示
catia.Visible = true;

// 新しいパートドキュメントを作成
Documents docs = catia.Documents;
Document doc = docs.Add("Part");
Part part = (Part)doc.Part;

// ユーザーから座標を入力
Console.WriteLine("始点の座標を入力してください (x1 y1 z1): ");
double x1 = double.Parse(Console.ReadLine());
double y1 = double.Parse(Console.ReadLine());
double z1 = double.Parse(Console.ReadLine());

Console.WriteLine("終点の座標を入力してください (x2 y2 z2): ");
double x2 = double.Parse(Console.ReadLine());
double y2 = double.Parse(Console.ReadLine());
double z2 = double.Parse(Console.ReadLine());

// 直線を描画
HybridShapeFactory factory = (HybridShapeFactory)part.HybridShapeFactory;
HybridShapeLinePtPt line = factory.AddNewLinePtPt(x1, y1, z1, x2, y2, z2);
part.Update();

Console.WriteLine("直線が描画されました。");
}
catch (Exception ex)
{
Console.WriteLine("エラーが発生しました: " + ex.Message);
}
}
}
}
```

---

### プログラムの説明

1. **CATIAの起動**
- `Activator.CreateInstance` を使用してCATIAアプリケーションのインスタンスを作成します。

2. **新しいパートドキュメントの作成**
- `Documents.Add("Part")` で新しいパートドキュメントを作成します。

3. **ユーザーからの座標入力**
- ユーザーに始点と終点の座標を入力させます。

4. **直線の描画**
- `HybridShapeFactory.AddNewLinePtPt` を使用して、指定された座標間に直線を描画します。

5. **エラーハンドリング**
- 例外をキャッチして、エラーメッセージを表示します。

---

### 必要な準備

1. **CATIAのタイプライブラリを参照に追加**
- Visual Studioでプロジェクトを開き、`参照`を右クリックして`COM参照の追加`を選択します。
- `CATIA Application` または `CATIA V5` を検索して参照に追加します。

2. **CATIAのインストール**
- CATIAが正しくインストールされ、ライセンスが有効であることを確認します。

3. **Visual Studio**
- C#プロジェクトを作成し、COM参照を追加できる環境を用意します。

---

### 注意点

- **CATIAのバージョン**
CATIAのAPIはバージョンによって異なる場合があります。使用しているCATIAのバージョンに合わせてAPIを確認してください。

- **エラーハンドリング**
CATIAの操作中にエラーが発生する可能性があるため、適切なエラーハンドリングを実装してください。

- **COMオブジェクトの解放**
C#ではガベージコレクションが自動的に行われますが、必要に応じて明示的にCOMオブジェクトを解放することもできます。

---

### 実行手順

1. Visual Studioで新しいC#コンソールアプリケーションプロジェクトを作成します。
2. 上記のコードを `Program.cs` に貼り付けます。
3. CATIAのタイプライブラリを参照に追加します。
4. プログラムをビルドして実行します。

プログラムを実行すると、CATIAが起動し、ユーザーが指定した座標に基づいて直線が描画されます。C#はCOMとの連携が簡単で、CATIAの操作に非常に適しています。

DLLの中身を逆Assembleして確認する Ildasm.exeで確認する

2024-07-04 02:20:54 | Visual C#

Ildasm.exe (IL 逆アセンブラー) | Microsoft Docs

Visual Basic.NETもVIsual C#も逆Assembleすると同じソースコードが出てくるらしい。要するに表現の仕方が違うだけの話。

例えば…

【リスト1:Visual Basic .NETサンプルコード】
Sub Proc1()
Dim x, y, z As Integer
x = 10
y = 20
z = x + y
Console.WriteLine(z)
End Sub

【リスト2:C#サンプルコード】
void Proc1()
{
int x, y, z;
x = 10;
y = 20;
z = x + y;
Console.WriteLine(z);
}

【リスト3:ILDASM.EXEで覗いてみると…】
.maxstack 2
.locals init ([0] int32 x,
[1] int32 y,
[2] int32 z)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldc.i4.s 20
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: add
IL_0009: stloc.2
IL_000a: ldloc.2
IL_000b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0010: ret

どちらも同じAssembleソースコードだ。

※ヤフオクでつまらない本に入札してしまった。




無料でPDFファイルとして公開されているものだ。


キャンセルしたい!
おそらく無料のパンフレットとして入手したものを出品しているだけの話で、有料の書籍として出版・販売されているものではないようだ。

アマゾンでも販売されているはずだから、アマゾンの出品の値段と比較してみようと思い、アマゾンで検索したら出て来なかったので、入札してしまった。

入札した後で「Visual Basic 移行」などの検索ワードで再度ググってみた結果、無料のPDFファイルとして出ていることが発覚した。

Visual Basic6.0からVIsual Basic.NETへのマイグレーションとかボッタクリ糞業者が広告を出しているのが判明したが、Visual Studioに移行・アップデートツールらしきものもあるらしい。


マイクロソフトがVB6からVB .NETへの移植支援ツールを公開

マイクロソフトがVB6からVB .NETへの移植支援ツールを公開

 Visual Basic .NETに移行するかどうか!)!)Visual Basic 6.0ユーザーにとって,今が正念場だ。2002年3月に出荷されたVisual Basic .NETは,その前のバージョンであるVisual...

日経クロステック(xTECH)



F#でAutoCADCHATBOTプログラムを書き換えてみた結果orz

2024-05-18 15:00:49 | Visual C#

C#でAutoCADCHATBOT動作確認に成功!

の記事の続編。

F#はVB.net同様、手動でのパス通しをする羽目になった。

open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry

type MyCommands() =
    interface IExtensionApplication with
        member this.Initialize() = 
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nMyCommands initialized")
        member this.Terminate() = 
            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nMyCommands terminated")

    [<CommandMethod("bot")>]
    member this.ProcessUserInput() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor
        ed.WriteMessage("\nProcessUserInput called")

        let userInput = this.GetStringFromUserInput("CAD", "何をしましょうか?")
        if userInput.Contains("直線") then
            this.CreateLine()
        elif userInput.Contains("円") then
            this.CreateCircle()
        else
            ed.WriteMessage("\nそのような操作はできません。")

    member private this.CreateLine() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor

        let start_x = this.GetDoubleFromUserInput("始点のX座標を入力してください。")
        let start_y = this.GetDoubleFromUserInput("始点のY座標を入力してください。")
        let end_x = this.GetDoubleFromUserInput("終点のX座標を入力してください。")
        let end_y = this.GetDoubleFromUserInput("終点のY座標を入力してください。")

        this.DrawLine(start_x, start_y, end_x, end_y)

    member private this.CreateCircle() =
        let doc = Application.DocumentManager.MdiActiveDocument
        let ed = doc.Editor

        let center_x = this.GetDoubleFromUserInput("中心のX座標を入力してください。")
        let center_y = this.GetDoubleFromUserInput("中心のY座標を入力してください。")
        let radius = this.GetDoubleFromUserInput("半径を入力してください。")

        this.DrawCircle(center_x, center_y, radius)

    member private this.GetDoubleFromUserInput(prompt: string) : double =
        let ed = Application.DocumentManager.MdiActiveDocument.Editor
        let mutable result = ed.GetDouble(prompt)
        while result.Status <> PromptStatus.OK do
            ed.WriteMessage("\n数値を入力してください。")
            result <- ed.GetDouble(prompt)
        result.Value

    member private this.GetStringFromUserInput(title: string, prompt: string) : string =
        let ed = Application.DocumentManager.MdiActiveDocument.Editor
        (ed.GetString(prompt)).StringResult

    member private this.DrawLine(startX: double, startY: double, endX: double, endY: double) =
        let doc = Application.DocumentManager.MdiActiveDocument
        let db = doc.Database

        use tr = db.TransactionManager.StartTransaction()
        let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
        let btr = tr.GetObject(bt.[BlockTableRecord.ModelSpace], OpenMode.ForWrite) :?> BlockTableRecord

        let startPoint = Point3d(startX, startY, 0.0)
        let endPoint = Point3d(endX, endY, 0.0)
        let line = new Line(startPoint, endPoint)
        btr.AppendEntity(line) |> ignore
        tr.AddNewlyCreatedDBObject(line, true) |> ignore

        tr.Commit()

    member private this.DrawCircle(centerX: double, centerY: double, radius: double) =
        let doc = Application.DocumentManager.MdiActiveDocument
        let db = doc.Database

        use tr = db.TransactionManager.StartTransaction()
        let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
        let btr = tr.GetObject(bt.[BlockTableRecord.ModelSpace], OpenMode.ForWrite) :?> BlockTableRecord

        let centerPoint = Point3d(centerX, centerY, 0.0)
        let circle = new Circle(centerPoint, Vector3d.ZAxis, radius)
        btr.AppendEntity(circle) |> ignore
        tr.AddNewlyCreatedDBObject(circle, true) |> ignore

        tr.Commit()

 

ACETUCS-BUTTON

というコマンドが勝手に呼び出され、ロード中・・・と表示されたままフリーズ・

誰もACETUCS-BUTTONなんていうコマンドを入力した覚えがないんだけど。

F#は使えない言語ということでソッコー没!

次はC++でためしてみることになった。

どうなるかわからんが、とりあえずChatGPTの吐いたソースコードをここに投げておこう。

#include "acutads.h"
#include "acedads.h"
#include "acdocman.h"
#include "dbents.h"
#include "dbmain.h"
#include "dbsymtb.h"
#include "dbapserv.h"
#include "geassign.h"
#include "acarray.h"

class MyCommands
{
public:
    static void ProcessUserInput()
    {
        AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
        AcDbBlockTable* pBlockTable;
        AcDbBlockTableRecord* pBlockTableRecord;

        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);
        pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
        pBlockTable->close();

        ACHAR szPrompt[512];
        acutPrintf(_T("\nCAD、何をしましょうか?: "));
        acedGetString(0, szPrompt);
        CString userInput = szPrompt;

        if (userInput.Find(_T("直線")) != -1)
        {
            CreateLine(pBlockTableRecord);
        }
        else if (userInput.Find(_T("円")) != -1)
        {
            CreateCircle(pBlockTableRecord);
        }
        else
        {
            acutPrintf(_T("\nそのような操作はできません。"));
        }

        pBlockTableRecord->close();
    }

private:
    static void CreateLine(AcDbBlockTableRecord* pBlockTableRecord)
    {
        double start_x = GetDoubleFromUserInput(_T("始点のX座標を入力してください。"));
        double start_y = GetDoubleFromUserInput(_T("始点のY座標を入力してください。"));
        double end_x = GetDoubleFromUserInput(_T("終点のX座標を入力してください。"));
        double end_y = GetDoubleFromUserInput(_T("終点のY座標を入力してください。"));

        AcDbLine* pLine = new AcDbLine(AcGePoint3d(start_x, start_y, 0), AcGePoint3d(end_x, end_y, 0));
        pBlockTableRecord->appendAcDbEntity(pLine);
        pLine->close();
    }

    static void CreateCircle(AcDbBlockTableRecord* pBlockTableRecord)
    {
        double center_x = GetDoubleFromUserInput(_T("中心のX座標を入力してください。"));
        double center_y = GetDoubleFromUserInput(_T("中心のY座標を入力してください。"));
        double radius = GetDoubleFromUserInput(_T("半径を入力してください。"));

        AcDbCircle* pCircle = new AcDbCircle(AcGePoint3d(center_x, center_y, 0), AcGeVector3d::kZAxis, radius);
        pBlockTableRecord->appendAcDbEntity(pCircle);
        pCircle->close();
    }

    static double GetDoubleFromUserInput(const ACHAR* prompt)
    {
        double value;
        ACHAR szPrompt[512];
        acutPrintf(prompt);
        acedInitGet(0, _T("Cancel"));
        if (RTNORM != acedGetReal(szPrompt, &value))
        {
            acutPrintf(_T("\n数値を入力してください。"));
            acutPrintf(_T("\n操作をキャンセルしました。"));
            acedGetPoint(nullptr, _T("\n続行するにはリターン キーを押してください。"));
            acutPrintf(_T("\n"));
            return -1.0;
        }
        return value;
    }
};

extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
    switch (msg)
    {
    case AcRx::kInitAppMsg:
        acrxDynamicLinker->unlockApplication(pkt);
        acrxRegisterAppMDIAware(pkt);
        break;
    case AcRx::kUnloadAppMsg:
        // Do nothing
        break;
    }
    return AcRx::kRetOK;
}

extern "C" void
ProcessUserInput()
{
    MyCommands::ProcessUserInput();
}


AutoCADでTETRIS!VisualC#ソースコードwww

2024-05-11 21:39:16 | Visual C#

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Threading;

namespace TetrisPlugin
{
public class TetrisSquare
{
public int X { get; set; }
public int Y { get; set; }
public string Color { get; set; }

public TetrisSquare(int x = 0, int y = 0, string color = "gray")
{
X = x;
Y = y;
Color = color;
}

public Point2d GetCord()
{
return new Point2d(X, Y);
}

public void SetColor(string color)
{
Color = color;
}

public string GetColor()
{
return Color;
}

public Point2d GetMovedCord(int direction)
{
int x = X;
int y = Y;

switch (direction)
{
case TetrisGame.MOVE_LEFT:
x--;
break;
case TetrisGame.MOVE_RIGHT:
x++;
break;
case TetrisGame.MOVE_DOWN:
y++;
break;
}

return new Point2d(x, y);
}
}

public class TetrisField
{
private readonly int width = 10; // Fix width and height
private readonly int height = 20;
private TetrisSquare[,] squares;

public TetrisField()
{
squares = new TetrisSquare[height, width];

for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
squares[y, x] = new TetrisSquare(x, y, "gray");
}
}
}

public int GetWidth()
{
return width;
}

public int GetHeight()
{
return height;
}

public TetrisSquare GetSquare(int x, int y)
{
return squares[y, x];
}

public bool JudgeGameOver(TetrisBlock block)
{
HashSet<Point2d> noEmptyCord = new HashSet<Point2d>();
HashSet<Point2d> blockCord = new HashSet<Point2d>();

for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() != "gray")
noEmptyCord.Add(new Point2d(x, y));
}
}

foreach (TetrisSquare square in block.GetSquares())
{
Point2d cord = square.GetCord();
blockCord.Add(cord);
}

blockCord.IntersectWith(noEmptyCord);

return blockCord.Count > 0;
}

public bool JudgeCanMove(TetrisBlock block, int direction)
{
HashSet<Point2d> noEmptyCord = new HashSet<Point2d>();

for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() != "gray")
noEmptyCord.Add(new Point2d(x, y));
}
}

HashSet<Point2d> moveBlockCord = new HashSet<Point2d>();

foreach (TetrisSquare square in block.GetSquares())
{
Point2d cord = square.GetMovedCord(direction);
moveBlockCord.Add(cord);

if (cord.X < 0 || cord.X >= width || cord.Y < 0 || cord.Y >= height)
return false;
}

moveBlockCord.IntersectWith(noEmptyCord);

return moveBlockCord.Count == 0;
}

public void FixBlock(TetrisBlock block)
{
foreach (TetrisSquare square in block.GetSquares())
{
int x = (int)square.GetCord().X;
int y = (int)square.GetCord().Y;
string color = square.GetColor();
squares[y, x].SetColor(color);
}
}

public void DeleteLine()
{
for (int y = height - 1; y >= 0; y--)
{
bool isFull = true;
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() == "gray")
{
isFull = false;
break;
}
}

if (isFull)
{
for (int yy = y; yy > 0; yy--)
{
for (int x = 0; x < width; x++)
{
squares[yy, x].SetColor(squares[yy - 1, x].GetColor());
}
}

for (int x = 0; x < width; x++)
{
squares[0, x].SetColor("gray");
}

y++;
}
}
}
}

public class TetrisBlock
{
private List<TetrisSquare> squares = new List<TetrisSquare>();

public TetrisBlock()
{
int blockType = new Random().Next(1, 5);

string color;
List<Point2d> cords = new List<Point2d>();

switch (blockType)
{
case 1:
color = "red";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2, 2));
cords.Add(new Point2d(10 / 2, 3));
break;
case 2:
color = "blue";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2 - 1, 1));
break;
case 3:
color = "green";
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2, 2));
break;
case 4:
color = "orange";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2 - 1, 1));
cords.Add(new Point2d(10 / 2 - 1, 2));
break;
default:
color = "gray";
break;
}

foreach (Point2d cord in cords)
{
squares.Add(new TetrisSquare((int)cord.X, (int)cord.Y, color));
}
}

public List<TetrisSquare> GetSquares()
{
return squares;
}

public void Move(int direction)
{
foreach (TetrisSquare square in squares)
{
Point2d movedCord = square.GetMovedCord(direction);
square.X = (int)movedCord.X;
square.Y = (int)movedCord.Y;
}
}
}

public class TetrisGame
{
private TetrisField field;
private TetrisBlock block;
private TetrisCanvas canvas;

public const int MOVE_LEFT = 0;
public const int MOVE_RIGHT = 1;
public const int MOVE_DOWN = 2;

public TetrisGame(TetrisCanvas canvas, TetrisField field, TetrisBlock block)
{
this.canvas = canvas;
this.field = field;
this.block = block;
}

public void Start(Action endFunc)
{
field = new TetrisField();
block = null;
canvas.Update(field, block);
}

public void NewBlock()
{
block = new TetrisBlock();

if (field.JudgeGameOver(block))
{
Console.WriteLine("GAMEOVER");
}

canvas.Update(field, block);
}

public void MoveBlock(int direction)
{
if (field.JudgeCanMove(block, direction))
{
block.Move(direction);
canvas.Update(field, block);
}
else
{
if (direction == MOVE_DOWN)
{
field.FixBlock(block);
field.DeleteLine();
NewBlock();
}
}
}
}

public class TetrisCanvas
{
private TetrisField beforeField;
private TetrisField field;
private readonly int BLOCK_SIZE = 25;
private readonly int FIELD_WIDTH = 10;
private readonly int FIELD_HEIGHT = 20;

public TetrisCanvas(TetrisField field)
{
this.field = field;
beforeField = field;
}

public void Update(TetrisField field, TetrisBlock block)
{
beforeField = field;

// Update canvas with new field and block
}
}

public class TetrisCommands
{
[CommandMethod("TETRIS")]
public void TetrisGame()
{
TetrisField field = new TetrisField();
TetrisBlock block = null;
TetrisCanvas canvas = new TetrisCanvas(field);
TetrisGame game = new TetrisGame(canvas, field, block);

game.Start(null); // You can pass a function to handle end game scenario

while (true)
{
// Get user input, for example through AutoCAD commands or UI buttons
// Depending on input, call game.MoveBlock(direction) with appropriate direction
}
}
}
}






プログラムを実行してみたが、エラーは出なかった。しかしAutoCADでTETRISとコマンドを入れたらそれっきりウンともスンとも言わなくなってしまった。


C#でAutoCADCHATBOT動作確認に成功!

2024-05-11 19:59:27 | Visual C#

前回はVisualBasic.netで成功させたから、今度はChatGPTにC#に変換してもらって試してみた。

※コマンド名に注目www



直線を書いてみた。


ソースコードの一部。


いわゆるパスを通すという作業の様子。

ここが躓いた原因。VB.NETの時はXMLタグを編集したがC#ではプロパティで開いて入力ボックスにacad.exeのディレクトリをフルパスで入力した。


いわゆる参照という作業の様子。

これはVB.NETの時と一緒。


using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

public class MyCommands
{
[CommandMethod("両足チョンパの崔バカ雄")]
public void ProcessUserInput()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

string userInput = GetStringFromUserInput("CAD", "何をしましょうか?");
if (userInput.Contains("直線"))
{
CreateLine();
}
else if (userInput.Contains("円"))
{
CreateCircle();
}
else
{
ed.WriteMessage("そのような操作はできません。");
}
}

private void CreateLine()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

double start_x = GetDoubleFromUserInput("始点のX座標を入力してください。");
double start_y = GetDoubleFromUserInput("始点のY座標を入力してください。");
double end_x = GetDoubleFromUserInput("終点のX座標を入力してください。");
double end_y = GetDoubleFromUserInput("終点のY座標を入力してください。");

DrawLine(start_x, start_y, end_x, end_y);
}

private void CreateCircle()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;

double center_x = GetDoubleFromUserInput("中心のX座標を入力してください。");
double center_y = GetDoubleFromUserInput("中心のY座標を入力してください。");
double radius = GetDoubleFromUserInput("半径を入力してください。");

DrawCircle(center_x, center_y, radius);
}

private double GetDoubleFromUserInput(string prompt)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

while (true)
{
PromptDoubleResult result = ed.GetDouble(prompt);
if (result.Status == PromptStatus.OK)
{
return result.Value;
}
else
{
ed.WriteMessage("数値を入力してください。");
}
}
}

private string GetStringFromUserInput(string title, string prompt)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

return ed.GetString(prompt).StringResult;
}

private void DrawLine(double startX, double startY, double endX, double endY)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;

using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

Point3d startPoint = new Point3d(startX, startY, 0);
Point3d endPoint = new Point3d(endX, endY, 0);
Line line = new Line(startPoint, endPoint);
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);

tr.Commit();
}
}

private void DrawCircle(double centerX, double centerY, double radius)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;

using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

Point3d centerPoint = new Point3d(centerX, centerY, 0);
Circle circle = new Circle(centerPoint, Vector3d.ZAxis, radius);
btr.AppendEntity(circle);
tr.AddNewlyCreatedDBObject(circle, true);

tr.Commit();
}
}
}

AutoCAD VB.NETマクロサンプル大全集に書かれてある通りにC#でもやればいいのではないかと思ったが、失敗してしまった。

以前購入したAmazon kindleの英語で書かれたe-bookを見ながらやってみたら、三度目の正直で成功!

VB.NETでは押出くり抜きとかもっと高度なことをやろうとしてChatGPTにコーディングしてもらったが、如何せんエラーが直らず断念。

C#ではもっと高度なことができると期待している。とりあえずVB.NETはこれにて終了。


C#用の逆コンパイラ .NET Reflector

2024-02-12 06:42:42 | Visual C#

C#の逆コンパイルができるらしい。さらにManaged C++ (C++/CLI)、Visual Basicにも対応しているとのことだが、
Managed C++ (C++/CLI)って何だ?C++言語にもいろいろ種類があるということか?Visual C++とは違うのか?違うとしたら何が、どこが違うのだろうか?

俺としてはWindowsアプリの大半がC++で書かれていると思っている。
巷に溢れている書籍には実務レベルに言及している本は皆無だ!そんな糞本をいくら読んでも自由自在にアプリが作れるようになるはずがない!!!

「こういう機能・動作をさせるには、この関数を使ってこんな風にプログラムを書く」ということが知りたいだけなのだ。糞本の著者のアホ共は、そんなにそういう内容を書くのが嫌なのか?そんなに知られたくないことなのか?バカなのか死ぬのか?知られてしまったらオマンマの食い上げで明日から仕事が無くなり、生きていけなくなるのか?どうしても知られたくない教えたくない機密事項・特許なのか?

Visual C#.net2003でAutoCAD2020のdllファイル参照追加をする方法

2023-09-10 03:31:05 | Visual C#
Visual C#.net2003(禿げ臆で確か3000円?で買った奴。Windows10にインストールできたが、ボタン等が文字化けして使いにくい。)でAutoCAD2020のdllファイル参照追加をしようとしたらエラーとなってできんかった。
ソースコード内に参照追加を直で書く方法があるんじゃないかと思ってChatGPTに訊いてみた結果・・・

User
VisualC#.net2003のソリューションエクスプローラーから autocad2020のacdbmgd.dll、accoremgd.dll、acmgd.dll、AcWindows.dllを参照追加しようとしたらエラーとなってできなかった。ソースコード内にに参照追加を記述するにはどう書けばよいか?

ChatGPT
Visual C# .NET 2003の開発環境では、通常はソリューションエクスプローラーから参照を追加する方法が主流ですが、時には手動でプロジェクトファイル(.csproj)に参照を追加する必要があります。以下は、手動でプロジェクトファイルに参照を追加する方法です。

プロジェクトファイルをテキストエディタで開きます。

プロジェクトファイル内で、<ItemGroup> タグ内に参照を追加します。各ライブラリについて、次のように記述します(ファイルパスは実際のインストールパスに合わせて修正してください)。

<ItemGroup>
<Reference Include="acdbmgd">
<HintPath>C:Program FilesAutodeskAutoCAD 2020acdbmgd.dll</HintPath>
</Reference>
<Reference Include="accoremgd">
<HintPath>C:Program FilesAutodeskAutoCAD 2020accoremgd.dll</HintPath>
</Reference>
<Reference Include="acmgd">
<HintPath>C:Program FilesAutodeskAutoCAD 2020acmgd.dll</HintPath>
</Reference>
<Reference Include="AcWindows">
<HintPath>C:Program FilesAutodeskAutoCAD 2020AcWindows.dll</HintPath>
</Reference>
</ItemGroup>

プロジェクトファイルを保存して閉じます。

Visual C# .NET 2003の開発環境を再起動するか、ソリューションエクスプローラーでプロジェクトをリフレッシュして変更を反映します。

これで、指定したライブラリへの参照が手動で追加されるはずです。注意点として、ファイルパスは実際の AutoCAD 2020 インストールパスに合わせて正確に指定する必要があります。また、Visual Studio 2003 は古いバージョンの開発環境であるため、新しいバージョンの AutoCAD 2020 との互換性についても確認することが重要です。

本当にできるんだろうな?

VisualC#で和文英訳AIを作るには?

2023-09-10 03:17:17 | Visual C#
俺:
VisualC#で和文英訳AIを作りたい。ソースコードを書いて。

ChatGPT:
和文英訳AIを作成するためには、機械翻訳モデルを利用するのが一般的です。以下は、Microsoft Translator Text APIを使用してC#で和文英訳AIを作成する基本的なスケルトンコードの一部です。このコードを使用するには、Microsoft Translator Text APIのアクセストークンが必要です。

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
static async Task Main(string[] args)
{
string apiKey = "YOUR_API_KEY_HERE"; // Microsoft Translator Text APIのAPIキーを設定

// 翻訳するテキスト
string textToTranslate = "こんにちは、世界!";

// 翻訳先の言語コード(英語は"en")
string targetLanguage = "en";

// Microsoft Translator Text APIのエンドポイント
string endpoint = "https://api.cognitive.microsofttranslator.com/";

try
{
using (var httpClient = new HttpClient())
{
// APIキーをヘッダーに追加
httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);

// 翻訳リクエストのパラメータを設定
var uri = $"{endpoint}/translate?api-version=3.0&to={targetLanguage}";
var requestBody = $"[{{'text':'{textToTranslate}'}}]";

// 翻訳リクエストを送信
var response = await httpClient.PostAsync(uri, new StringContent(requestBody, System.Text.Encoding.UTF8, "application/json"));

// 翻訳結果を取得
var jsonResponse = await response.Content.ReadAsStringAsync();
Console.WriteLine(jsonResponse);
}
}
catch (Exception ex)
{
Console.WriteLine($"翻訳エラー: {ex.Message}");
}
}
}
このコードでは、Microsoft Translator Text APIを使用して指定したテキストを指定した言語に翻訳することができます。APIキーを正しく設定し、必要なエラーハンドリングを追加してください。

なお、APIキーの取得方法やAPIエンドポイントの詳細については、Microsoftの公式ドキュメントを参照してください。

C#でソースコード生成AIを作るには?

2023-09-10 02:52:32 | Visual C#
User
自然言語処理によるソースコード生成AIをVisual C#で作りたい。ソースコードを書いて
ChatGPT
自然言語処理によるソースコード生成AIをVisual C#で作成するためのコード例は非常に複雑ですが、基本的なステップを示します。以下は、参考として利用できるコードの一部です。完全なプロジェクトには、多くの追加のコードとリソースが必要です。

必要なライブラリをインストール:

sql
Copy code
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.ML;
using Microsoft.ML.Data;
データモデルを定義:

csharp
Copy code
public class SourceCodeData
{
[LoadColumn(0)]
public string NaturalLanguageDescription;

[LoadColumn(1)]
public string GeneratedCode;
}
モデルの訓練と評価:

mathematica
Copy code
var context = new MLContext();
var data = context.Data.LoadFromTextFile<SourceCodeData>("sourcecode.txt", separatorChar: ',');

var pipeline = context.Transforms.Conversion.MapValueToKey("NaturalLanguageDescriptionKey")
.Append(context.Transforms.Text.FeaturizeText("NaturalLanguageDescriptionFeatures", "NaturalLanguageDescription"))
.Append(context.Transforms.Text.TokenizeIntoWords("NaturalLanguageDescriptionTokens", "NaturalLanguageDescription"))
.Append(context.Transforms.Text.NormalizeText("NaturalLanguageDescriptionNormalized", "NaturalLanguageDescriptionTokens"))
.Append(context.Transforms.Text.ProduceNgrams("NaturalLanguageDescriptionNgrams", "NaturalLanguageDescriptionNormalized"))
.Append(context.Transforms.Text.TermFrequency("NaturalLanguageDescriptionTermFrequency", "NaturalLanguageDescriptionNgrams"))
.Append(context.Transforms.Conversion.MapValueToKey("GeneratedCodeKey"))
.Append(context.Transforms.Text.TokenizeIntoWords("GeneratedCodeTokens", "GeneratedCode"))
.Append(context.Transforms.Text.NormalizeText("GeneratedCodeNormalized", "GeneratedCodeTokens"))
.Append(context.Transforms.Text.ProduceNgrams("GeneratedCodeNgrams", "GeneratedCodeNormalized"))
.Append(context.Transforms.Text.TermFrequency("GeneratedCodeTermFrequency", "GeneratedCodeNgrams"))
.Append(context.Transforms.Concatenate("Features", "NaturalLanguageDescriptionTermFrequency", "GeneratedCodeTermFrequency"))
.Append(context.Transforms.NormalizeMinMax("Features"))
.Append(context.Transforms.Conversion.MapKeyToValue("GeneratedCode"));

var trainer = context.Regression.Trainers.FastTree();
var trainingPipeline = pipeline.Append(trainer);

var trainedModel = trainingPipeline.Fit(data);

var predictions = trainedModel.Transform(data);
var metrics = context.Regression.Evaluate(predictions);
自然言語からコードを生成:

csharp
Copy code
var description = "自然言語からC#コードを生成してください。";
var predictor = context.Model.CreatePredictionEngine<SourceCodeData, SourceCodePrediction>(trainedModel);
var prediction = predictor.Predict(new SourceCodeData { NaturalLanguageDescription = description });
Console.WriteLine($"Generated Code: {prediction.GeneratedCode}");
このコード例は、ML.NETを使用して自然言語の説明からソースコードを生成する基本的なスケルトンです。詳細な実装には多くの調整とトレーニングデータが必要です。また、モデルの品質向上やセキュリティの検討も重要です。

Visual Studio Code上にC#開発環境を構築する方法

2023-06-17 17:20:07 | Visual C#

Microsoft、Visual Studio Code上にC#開発環境を構築できる拡張機能「C# Dev Kit」を発表

https://codezine.jp/article/detail/17892

https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit

これからVisual C#を始めようとしていてVisual Studio Communityのインストールで悩んでいる者に朗報?

特にCドライブがいっぱいでインストールできない者にとって有効か?

俺もその一人。AutoCADとかごついアプリばかり入っていてCドライブの容量を圧迫されている場合、深刻な問題だ。

どうあがいてもCドライブにインストールされてしまうので、VSCodeしか入れられなかった。

Visual Studio Code上で開発環境を構築できるらしい。