CyberChaos(さいばかおす)

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

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はこれにて終了。


BIMクラウドもビックリ!Jw_cad図面を3D、4D、5D化する「K-engine」

2024-05-11 15:44:47 | アイデア起業・アイデア売買

https://ken-it.world/it/2014/09/k-engine.html

より引用。

Jw_cadの図面からクラウドで作られた3Dモデルの外観

LIXILグループのK-engine(本社:東京都新宿区)は、これまで約1週間(約1万分)かかっていた見積もり作業をわずか5分に短縮する画期的なクラウドシステム「K-engineサービス」をこのほどスタートさせました。

Jw_cadの図面データをクラウドにアップロードし、簡単な設定を行えば、わずか2分間で施主への見積書や実行予算などを正確に計算してデータを戻してくれるというシステムなのです。

Jw_cadの図面から住宅の壁や部屋などの寸法や、システムキッチンなどの建材設備などを拾い出し、それらに単価をかけて集計するのは、BIM(ビルディング・インフォメーション・モデリング)ソフトも顔負けです。

なぜ、こんなことができるかというと、Jw_cadの図面データにある「レイヤー」をBIMの属性情報代わりに使用し、クラウドが部材の種類などを区別できるようにしているからです。

図面上のデータは「3D部品」として分解され、住宅全体を3Dモデルとして作成します。これらの機能を実現するエンジンは、福井コンピュータアーキテクトの3D住宅設計システム「Architrend-Z」のものが採用されているとのことです。そのため、Jw_cadの図面のほかArchitrend-Zの図面データでも見積もりなどが可能です。

その他・・・

施主用の見積書や実行予算書を作成

工程表まで自動作成

 

これはすごいと思った。しかし、Revit等のBIMの牙城をとこまで攻め崩せるかが見ものだ。

建築VRのUnityやUnrealEngineもあることだし。


【熊谷組】CADデータからBIMモデルを生成するシステム「CABTrans」を開発

2024-05-11 15:31:37 | アイデア起業・アイデア売買

https://www.kumagaigumi.co.jp/news/2024/pr_20240422_1.html

より引用。

今回開発した「CABTrans」は大きく2つのモジュールに分かれています。
ひとつは、燈社が開発した、CADデータから情報を取得し構造化されたCSVデータを出力するモジュール「D-CSV」、もうひとつは熊谷組が担当したCSVを読み込み、CSVからRhino-Grasshopper※1を経由してArchicad※2上にBIMモデルを生成するモジュールです。

「D-CSV」はブラウザ上で動作し、図面から範囲・レイヤー等を指定することでAIによって柱・梁・基礎・杭の位置情報及び断面情報を取得し、CSV形式で出力します。さらに、生成したCSVファイルをGrasshopperで構築したアルゴリズムにより処理することで鉄骨及びRC構造フレーム部分をArchicad上に生成することが可能です。現状は、構造図CADデータからの構造部分BIMデータの変換にのみ対応しています。

 

CABTransのサイトを見た俺の感想。

JWCADで3Dが可能になったのかと一瞬思ってしまった。

現状ではやはりJWCADで2.5Dまでが精いっぱいだ。かと言っていきなりBIMでモデリングするのもまだまだ敷居が高い。


COBOL埋め込みSQLの例をChatGPTに書かせた。

2024-05-11 12:48:55 | COBOL

IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.

ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SQL-STATEMENT PIC X(100).
01 SQL-RESULT PIC S9(4) COMP.

PROCEDURE DIVISION.
MAIN-PROCEDURE.
    MOVE "SELECT * FROM EMPLOYEES WHERE DEPARTMENT = 'SALES'" TO SQL-STATEMENT.
    EXEC SQL
        PREPARE SQL-STATEMENT
        END-EXEC.
    EXEC SQL
        OPEN EMPLOYEE-CURSOR
        END-EXEC.
    EXEC SQL
        FETCH NEXT FROM EMPLOYEE-CURSOR INTO :EMPLOYEE-ID, :EMPLOYEE-NAME
        END-EXEC.
    PERFORM UNTIL SQL-RESULT = 100
        DISPLAY "EMPLOYEE ID: " EMPLOYEE-ID " EMPLOYEE NAME: " EMPLOYEE-NAME
        EXEC SQL
            FETCH NEXT FROM EMPLOYEE-CURSOR INTO :EMPLOYEE-ID, :EMPLOYEE-NAME
            END-EXEC.
    END-PERFORM.
    EXEC SQL
        CLOSE EMPLOYEE-CURSOR
        END-EXEC.
    STOP RUN.

このプログラムは、部署が "SALES" の従業員を表示する単純な例です。SQL文は文字列変数SQL-STATEMENTに格納され、EXEC SQLステートメントによって実行されます。このコードは、実際のデータベース接続や設定には関係なく、SQL文の埋め込み方法を示しています。

実際には、プログラム内で使用するデータベースにアクセスするためには、データベース接続情報などの追加の設定が必要です。また、プリプロセッサを使用してCOBOLプログラムを生成するための手順もありますが、この手順はCOBOLの特定のコンパイラに依存します。

とのこと。

https://amzn.asia/d/8BeCip1

COBOLエンジニアのためのOracle/SQLレッスン

という本のレビュー覧で「COBOL埋め込みSQL」という文言が出てきたので、気になっていた。

レビューではさんざんなことが書かれていたが、このレビューをきっかけにPython埋め込みVisualBasic.netとかいろいろ閃いた。

さらにこんな情報も・・・

https://itpfdoc.hitachi.co.jp/manuals/3020/30203D6240/USR20403.HTM

https://software.fujitsu.com/jp/manual/manualfiles/M080271/J2X02268/06Z201/aplsq03/aplsq062.html

https://software.fujitsu.com/jp/manual/manualfiles/m140016/j2ul1756/03z200/j2ul-1756-03z0.pdf

Googleで「cobol 埋め込みsql」と入力して検索すべし。