当前位置: 首页 > 工具软件 > DouZero > 使用案例 >

斗地主AI Douzero resnet 动态库插件,C++, C#, Python, QT, Android, 火山, 易语言调用

金瑞
2023-12-01

介绍

基于快手AI平台部开发的DouZero。
官网地址:
https://github.com/kwai/DouZero
https://github.com/Vincentzyx/Douzero_Resnet

完整示例代码下载地址:
https://pan.baidu.com/s/1usCZccS-TPtkFhdExbBPmw?pwd=dddd
https://www.aliyundrive.com/s/iqZsWSQGk8B

演示视频地址:
https://www.bilibili.com/video/BV1iP41127iT/

C++:

//# Author: QQ 1720191365
//# Created Time:2023-04
#include <windows.h>
#include <iostream>
#include <string>
#include <thread>

using namespace std;
HMODULE module = LoadLibrary("..\\..\\Dnn.dll");

typedef char* (_stdcall* _getWinrate)(int type, const char* myCards);
_getWinrate getWinrate = (_getWinrate)GetProcAddress(module, "getWinrate");

typedef char* (_stdcall* _initCard)(int id, int play, const char* myCards, const char* threeCards, const char* passWord);
_initCard initCard = (_initCard)GetProcAddress(module, "initCard");

typedef char* (_stdcall* _getCard)(int id, const char* nextCards, const char* prevCards);
_getCard getCard = (_getCard)GetProcAddress(module, "getCard");

void fun(int id) {
	string src, str, res, md5, three;
	src = "345566689TTJQKAA222X", three = "46T";
	res = getWinrate(4, src.c_str()); cout << "Winrate: " << res << endl;

	str = initCard(id, 0, src.c_str(), three.c_str(), md5.c_str());
	cout << "*手牌: " << src << " : " << str << endl;

	res = getCard(id, "", ""); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "A"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "0"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "JJ"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "0"); cout << "*出牌: " << res << endl;
	res = getCard(id, "9TJQKA", "0"); cout << "*出牌: " << res << endl;
	res = getCard(id, "3", "8"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "D"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "77"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "0"); cout << "*出牌: " << res << endl;
	res = getCard(id, "0", "0"); cout << "*出牌: " << res << endl;
}

int main() {
	constexpr auto TH = 11;
	thread threads[TH];

	for (short t = 0; t < 11; t++) {

		for (short i = 0; i < TH; ++i) { threads[i] = thread(fun, i + 1); }

		for (auto& thr : threads) { thr.join(); }

		Sleep(1000);
	}

	system("pause");
	FreeLibrary(module);
	return 1;
}

C#:

using System;
using System.Runtime.InteropServices;

namespace CSharpTest
{
    internal class Program
    {
        [DllImport("..\\..\\Dnn.x64.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern IntPtr getWinrate(int type, string myCards);
        
        [DllImport("..\\..\\Dnn.x64.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern IntPtr initCard(int id, int play, string myCards, string threeCards, string passWord);
        
        [DllImport("..\\..\\Dnn.x64.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern IntPtr getCard(int id, string nextCards, string prevCards);
        
        static void Main()
        {
            string src = "345566689TTJQKAA222X", three = "46T"; int id = 0;
            
            IntPtr res = getWinrate(4, src);
            Console.WriteLine("Winrate:" + Marshal.PtrToStringAnsi(res));

            res = initCard(id, 0, src, three, "");
            Console.WriteLine("*initCard: " + src + ": " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "", ""); 
            Console.WriteLine("AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "A");
            Console.WriteLine("0    A   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "0");
            Console.WriteLine("0    0   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "JJ");
            Console.WriteLine("0    JJ  AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "0");
            Console.WriteLine("0    0   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "9TJQKA", "0");
            Console.WriteLine("9TJQKA   0   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "3", "8");
            Console.WriteLine("3    8   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "D");
            Console.WriteLine("0    D   AI出牌: " + Marshal.PtrToStringAnsi(res));

            res = getCard(id, "0", "77");
            Console.WriteLine("0    77  AI出牌: " + Marshal.PtrToStringAnsi(res));
        }
    }
}

Python:

from ctypes import *

pDll = CDLL("../Dnn.x64.dll")

pDll.getWinrate.restype = c_char_p
pDll.initCard.restype = c_char_p
pDll.getCard.restype = c_char_p

res = pDll.getWinrate(4, b'345566689TTJQKAA222X')
print("Winrate:", res.decode('GBK'))

res = pDll.initCard(0, 0, b'345566689TTJQKAA222X', b'46T', b'')
print("*initCard: ", res.decode('GBK'))

res = pDll.getCard(0, b'', b'')
print("AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'A')
print("0    A   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'0')
print("0    0   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'JJ')
print("0    JJ  AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'0')
print("0    0   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'9TJQKA', b'')
print("9TJQKA   0   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'3', b'8')
print("3    8   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'D')
print("0    D   AI出牌: ", res.decode('GBK'))

res = pDll.getCard(0, b'0', b'77')
print("0    77  AI出牌: ", res.decode('GBK'))

QT:

#include "QLibrary"
#include <QCoreApplication>

typedef char *(*getWinrate_)(int types, const char *myCards);
getWinrate_ getWinrate;

typedef char *(*initCard_)(int id, int play, const char* myCards, const char* threeCards, const char* passWord);
initCard_ initCard;

typedef char *(*getCard_)(int id, const char* nextCards, const char* prevCards);
getCard_ getCard;

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QLibrary *lib = new QLibrary("..\\..\\Dnn.x64.dll");
    if (!lib->load()) { return 0; }

    qDebug() << "DLL加载成功";

    getWinrate = (getWinrate_)lib->resolve("getWinrate");
    initCard = (initCard_)lib->resolve("initCard");
    getCard = (getCard_)lib->resolve("getCard");

    char card[] = "345566689TTJQKAA222X", three[] = "46T";

    qDebug() << QString::fromLocal8Bit(getWinrate(4, card));

    qDebug() << QString::fromLocal8Bit(initCard(0, 0, card, three, ""));

    qDebug() << QString::fromLocal8Bit(getCard(0, "", ""));

    qDebug() << QString::fromLocal8Bit(getCard(0, "0", "A"));

    qDebug() << QString::fromLocal8Bit(getCard(0, "0", "0"));

    qDebug() << QString::fromLocal8Bit(getCard(0, "0", "JJ"));

    return 1;
}

Android:

package com.example.aicpp20;

import android.content.res.AssetManager;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.aidemo.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {
    static {
        System.loadLibrary("aicpp20");
    }
    private ActivityMainBinding binding;
    public MainActivity() {
    }
    //# Author: QQ 1720191365
    //# Created Time:2023-04
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        TextView tv = binding.sampleText;

        setNativeAssetManager(getAssets());

        String str = "345566689TTJQKAA222X";
        tv.setText(str);

        //str = getWinrate(4,"345566689TTJQKAA222X");
        //str = "\n评分: " + str;
        //tv.setText(str);

        String res = initCard(0,0,"345566689TTJQKAA222X","46T","");
        str = str + "\ninitCard: " + res;
        tv.setText(str);

        res = getCard(0,"","");
        str = str + "\nAI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"0","A");
        str = str + "\n0    A   AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"0","0");
        str = str + "\n0    0   AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"0","JJ");
        str = str + "\n0    JJ  AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"0","0");
        str = str + "\n0    0   AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"9TJQKA","0");
        str = str + "\n9TJQKA   0   AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"3","8");
        str = str + "\n3    8   AI出牌: " + res;
        tv.setText(str);

        res = getCard(0,"0","D");
        str = str + "\n0    D   AI出牌: " + res;
        tv.setText(str);
        
        res = getCard(0,"0","77");
        str = str + "\n0    77  AI出牌: " + res;
        tv.setText(str);
    }
    private native String getWinrate(int type, String myCards);
    private native String initCard(int id, int play, String myCards, String threeCards, String passWord);
    private native String getCard(int id, String nextcards, String prevcards);
    public native void setNativeAssetManager(AssetManager assetManager);
}

火山中文编程语言:

<火山程序 类型 = "通常" 版本 = 1 />

包 火山.程序 <注释 = "//# Author: QQ 1720191365" 注释 = "//# Created Time:2023-04">

类 启动类 <公开 基础类 = 窗口程序类 折叠>
{
    变量 主窗口对象 <类型 = 我的主窗口>

    方法 启动方法 <公开 类型 = 整数>
    {
        主窗口对象.创建主窗口 ()
        返回 (1)
    }
}

# ===

类 我的主窗口 <基础类 = 窗口 注释 = "样例主窗口" @视窗.布局 = "client_size = \"500, 300\"" 标题 = "我的主窗口">
{
    变量 按钮1 <类型 = 按钮 折叠 折叠2 隐藏值属性 = "0" @视窗.布局 = "id = 101\r\npos = \"324, 256, 70, 32\"" 标题 = "测试">
    变量 按钮2 <类型 = 按钮 折叠2 隐藏值属性 = "0" @视窗.布局 = "id = 102\r\npos = \"414, 256, 70, 32\"" 标题 = "退出">
    变量 编辑框1 <类型 = 编辑框 折叠2 隐藏值属性 = "0" @视窗.布局 = "id = 103\r\npos = \"10, 6, 480, 237\"" 是否允许多行 = 真>

    方法 我的主窗口_创建完毕 <接收事件 类型 = 整数 注释 = "当本组件及其中所有子组件均被创建完毕后发送此事件." 折叠>
    参数 来源对象 <类型 = 我的主窗口 注释 = "提供事件产生的具体来源对象">
    参数 标记值 <类型 = 整数 注释 = "用户调用\"挂接事件\"命令时所提供的\"标记值\"参数值,非此方式挂接事件则本参数值固定为0.">
    {
        返回 (0)
    }

    方法 getWinrate <公开 静态 类型 = 整数 注释 = "" 注释 = "" 注释 = " " @输出名 = "getWinrate"
            @视窗.输入 = "..\\..\\..\\..\\..\\..\\Dnn.dll">
    参数 types <类型 = 整数>
    参数 myCards <类型 = 变整数>

    方法 initCard <公开 静态 类型 = 整数 注释 = "" 注释 = "" 注释 = " " @输出名 = "initCard"
            @视窗.输入 = "..\\..\\..\\..\\..\\..\\Dnn.dll">
    参数 id <类型 = 整数>
    参数 play <类型 = 整数>
    参数 myCards <类型 = 变整数>
    参数 threeCards <类型 = 变整数>
    参数 passWord <类型 = 变整数>

    方法 getCard <公开 静态 类型 = 整数 注释 = "" 注释 = "" 注释 = " " @输出名 = "getCard"
            @视窗.输入 = "..\\..\\..\\..\\..\\..\\Dnn.dll">
    参数 id <类型 = 整数>
    参数 nextCards <类型 = 变整数>
    参数 prevCards <类型 = 变整数>

    方法 按钮_被单击 <接收事件 类型 = 整数 注释 = "当按钮被单击后发送此事件">
    参数 来源对象 <类型 = 按钮 注释 = "提供事件产生的具体来源对象">
    参数 标记值 <类型 = 整数 注释 = "用户调用\"挂接事件\"命令时所提供的\"标记值\"参数值,非此方式挂接事件则本参数值固定为0.">
    {
        变量 结果 <类型 = 文本型>
        如果 (来源对象 == 按钮2)
        {
            结束 ()
        }
        如果 (来源对象 == 按钮1)
        {

            结果 = 多字节指针到文本 (getWinrate (4, 取字节集指针 (文本到多字节 ("345566689TTJQKAA222X", ))))
            编辑框1.加入文本 ("*局前评估: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (initCard (0, 0, 取字节集指针 (文本到多字节 ("345566689TTJQKAA222X", )), 取字节集指针 (文本到多字节 ("46T", )), 取字节集指针 (文本到多字节 ("", ))))
            编辑框1.加入文本 ("*创建牌局: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("", )), 取字节集指针 (文本到多字节 ("", ))))
            编辑框1.加入文本 ("AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("A", ))))
            编辑框1.加入文本 ("0    A   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("0", ))))
            编辑框1.加入文本 ("0    0   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("JJ", ))))
            编辑框1.加入文本 ("0    JJ  AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("0", ))))
            编辑框1.加入文本 ("0    0   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("9TJQKA", )), 取字节集指针 (文本到多字节 ("0", ))))
            编辑框1.加入文本 ("9TJQKA   0   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("3", )), 取字节集指针 (文本到多字节 ("8", ))))
            编辑框1.加入文本 ("3    8   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("D", ))))
            编辑框1.加入文本 ("0    D   AI出牌: " + 结果 + "\r\n")

            结果 = 多字节指针到文本 (getCard (0, 取字节集指针 (文本到多字节 ("0", )), 取字节集指针 (文本到多字节 ("77", ))))
            编辑框1.加入文本 ("0    77  AI出牌: " + 结果 + "\r\n")

        }
        返回 (0)
    }
}

 类似资料: