C/C++实现算24点小游戏

算24点小游戏

说明

分别使用C语言和C++实现算24点小游戏。考虑到会出现相同的数字组合,如果不排除就会产生重复结果,因此,用C语言实现了简单的set功能, C++则可以直接使用STL。


C file struct
 	|----cal24
 		|----cal24.h
 		|----cal24.c
 		|----set.h
 		|----set.c
 	|----main.c
 	|----CMakeLists.txt

C++ file struct
 	|----cal24
 		|----cal24.hpp
 	|----main.cpp
 	|----CMakeLists.txt

C代码

set.h

#ifndef __SET_H__
#define __SET_H__

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

struct _node;

typedef struct _node{
    void *val;
    struct _node *next;
} node;

typedef struct {
    int size;
    node *begain;
} set;

void set_insert(set *s, void *x, int data_size);
void set_free(set *s);


#endif

set.c

#include "set.h"

void set_insert(set *s, void *x, int data_size)
{
    node *v = (node *)calloc(1, sizeof(node));
    v->val = malloc(data_size);
    memcpy(v->val, x, data_size);
    v->next = NULL;
    if(!s->begain) {
        s->size = 1;
        s->begain = v;
       
    } else {
        node *t = s->begain;
        node *p = NULL;
        char *insertv = (char*)v->val;
        while(t) {
            char *curr = (char *)t->val;
            int countequal = 0;
            for(int i=0; i<data_size; ++i) 
                countequal += (curr[i] == insertv[i]);
            if(countequal == data_size)
                return;
            p = t;
            t = t->next;
        }
        p->next = v;
        ++s->size;
    }
}

void set_free(set *s) 
{
    node *t = s->begain;
    node *x = t;
    while(t) {
        x = t->next;
        free(t->val);
        free(t);
        t = x;
    }
    s->size = 0;
}

cal24.h

#ifndef __CAL24_H__
#define __CAL24_H__

#include "math.h"
#include "set.h"

#ifdef __cplusplus
extern "C" {
#endif
enum oper {add, sub, mul, _div};

void get_number_list(set *s, float a, float b, float c ,float d);
int cal24(set *s);

#ifdef __cplusplus
}
#endif
#endif

cal24.c

#include "cal24.h"

const char operc[5] = {'+', '-', '*', '/'};
int num = 0;

float oper_cal(float x, float y, enum oper c)
{
    float res = 0;
    switch (c) {
        case add: res = x + y; break;
        case sub: res = x - y; break;
        case mul: res = x * y; break;
        case _div: res = x / (y != 0 ? y : 0.01); break; 
    };
    return res;
}

void bracket_cal(float a, float b, float c, float d, enum oper *cal) 
{
    float y = oper_cal(oper_cal(oper_cal(a, b, cal[0]), c, cal[1]), d, cal[2]);
    if((fabs(y - 24.0) < 0.01)) {
        ++num;
        printf("((%.0f %c %.0f) %c %.0f) %c %.0f = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
    }
    y = oper_cal(oper_cal(a, b, cal[0]), oper_cal(c, d, cal[2]), cal[1]);
    if((fabs(y - 24.0) < 0.01)) {
        ++num;
        printf("(%.0f %c %.0f) %c (%.0f %c %.0f) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
    }
    y = oper_cal(oper_cal(a, oper_cal(b, c, cal[1]), cal[0]), d, cal[2]);
    if((fabs(y - 24.0) < 0.01)) {
        ++num;
        printf("(%.0f %c (%.0f %c %.0f)) %c %.0f = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
    }
    y = oper_cal(a, oper_cal(oper_cal(b, c, cal[1]), d, cal[2]), cal[0]);
    if((fabs(y - 24.0) < 0.01)) {
        ++num;
        printf("%.0f %c ((%.0f %c %.0f) %c %.0f) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
    }
    y = oper_cal(a, oper_cal(b, oper_cal(c, d, cal[2]), cal[1]), cal[0]);
    if((fabs(y - 24.0) < 0.01)) {
        ++num;
        printf("%.0f %c (%.0f %c (%.0f %c %.0f)) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
    }
}

int cal24(set *s)
{
    float a,b,c,d;
    float data[4];
    enum oper cal[3] = {add, add, add};
    node *t = s->begain;
    printf("data has %d group(s) total\n", s->size);
    while(t) {
        memcpy(data, t->val, 4*sizeof(float));
        a = data[0];
        b = data[1];
        c = data[2];
        d = data[3];
        for(enum oper c1 = add; c1 <= _div; ++c1) {
            cal[0] = c1;
            for(enum oper c2 = add; c2 <= _div; ++c2) {
                cal[1] = c2;
                for(enum oper c3 = add; c3 <= _div; ++c3) {
                    cal[2] = c3;
                    bracket_cal(a, b, c, d, cal);
                }
            }
        }      
        t = t->next;
    }
    return num;
}

void  get_number_list(set *s, float a, float b, float c ,float d)
{
    float nums[4] = {a, b, c, d};
    float t1, t2, t3, t4;
    
    for(int i=0; i<4; ++i) {
        t1 = nums[i];
        for(int j=0; j<4; ++j) {
            if(j != i) {
                t2 = nums[j];
                for(int k=0; k<4; ++k) {
                    if((k != i) && (k != j)) {
                        t3 = nums[k];
                        for(int r=0; r<4; ++r) {
                            if((r!=i) && (r !=j) &&(r !=k)) {
                                t4 = nums[r];
                                float insert[4] = {t1, t2, t3, t4};
                                set_insert(s, (void*)insert, 4*sizeof(float));
                            }
                        }
                    }
                }   
            }
        }
    }
}

main.c

#include "cal24.h"
#include "stdio.h"
#define OPER(x,y,op) x op y

int main(void *arg)
{
    float a, b, c, d;
    set *s = (set *)calloc(1, sizeof(set));
    s->size = 0;
    s->begain = NULL;
    
    printf("input 1st numbers:");
    scanf("%f", &a);
    printf("input 2nd numbers:");
    scanf("%f", &b);
    printf("input 3th numbers:");
    scanf("%f", &c);
    printf("input 4th numbers:");
    scanf("%f", &d);
    
    get_number_list(s, a, b, c, d);
    int num = cal24(s);
    printf("input numbers are %.0f, %.0f, %.0f, %.0f\n", a, b, c, d);
    printf("There are %d calculation methods", num);
    set_free(s);
    free(s);
    return 0;
}

CMakeLists.txt

project(test)
cmake_minimum_required(VERSION 3.24)

aux_source_directory(cal24 APP_SRC)
include_directories(cal24)

add_executable(${PROJECT_NAME} main.c ${APP_SRC})

C++代码

cal24.hpp

#ifndef __CAL24_HPP__
#define __CAL24_HPP__
#include <math.h>
#include <stdio.h>
#include <array>
#include <set>

enum oper {add, sub, mul, _div, other};
const char operc[5] = {'+', '-', '*', '/'};

oper &operator++(oper &d) 
{
    return d = (d == other) ? oper::add : oper(d+1);
}

static float oper_cal(float x, float y, enum oper c)
{
    float res = 0;
    switch (c) {
        case add: res = x + y; break;
        case sub: res = x - y; break;
        case mul: res = x * y; break;
        case _div: res = x / (y != 0 ? y : 0.01); break; 
    };
    return res;
}

class Cal24 {
    float a;
    float b;
    float c;
    float d;
    int num;
    std::set<std::array<float, 4>> data;

    void cal_numbers(const float &a, const float &b, const float &c, const float &d, enum oper *cal) 
    {
        float y = oper_cal(oper_cal(oper_cal(a, b, cal[0]), c, cal[1]), d, cal[2]);
        if((fabs(y - 24.0) < 0.01)) {
            ++num;
            printf("((%.0f %c %.0f) %c %.0f) %c %.0f = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
        }
        y = oper_cal(oper_cal(a, b, cal[0]), oper_cal(c, d, cal[2]), cal[1]);
        if((fabs(y - 24.0) < 0.01)) {
            ++num;
            printf("(%.0f %c %.0f) %c (%.0f %c %.0f) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
        }
        y = oper_cal(oper_cal(a, oper_cal(b, c, cal[1]), cal[0]), d, cal[2]);
        if((fabs(y - 24.0) < 0.01)) {
            ++num;
            printf("(%.0f %c (%.0f %c %.0f)) %c %.0f = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
        }
        y = oper_cal(a, oper_cal(oper_cal(b, c, cal[1]), d, cal[2]), cal[0]);
        if((fabs(y - 24.0) < 0.01)) {
            ++num;
            printf("%.0f %c ((%.0f %c %.0f) %c %.0f) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
        }
        y = oper_cal(a, oper_cal(b, oper_cal(c, d, cal[2]), cal[1]), cal[0]);
        if((fabs(y - 24.0) < 0.01)) {
            ++num;
            printf("%.0f %c (%.0f %c (%.0f %c %.0f)) = 24\n",a, operc[cal[0]], b, operc[cal[1]], c, operc[cal[2]], d);
        }
    }

    void cal24(const float &a, const float &b, const float &c, const float &d)
    {
        oper cal[3] = {add, add, add};
        for(oper c1 = add; c1 <= _div; ++c1) {
            cal[0] = (oper)c1;
            for(oper c2 = add; c2 <= _div; ++c2) {
                cal[1] = (oper)c2;
                for(oper c3 = add; c3 <= _div; ++c3) {
                    cal[2] = (oper)c3;
                    cal_numbers(a, b, c, d, cal);
                }
            }
        }
    }
    void init_set()
    {
        num = 0;
        data.swap(std::set<std::array<float, 4>>());
        std::array<float, 4> input({a, b, c, d});
        float t1 = 0., t2 = 0., t3 = 0., t4 = 0.;
        for(int i=0; i<4; ++i) {
            t1 = input[i];
            for(int j=0; j<4; ++j) {
                if(j != i) {
                    t2 = input[j];
                    for(int k=0; k<4; ++k) {
                        if((k != i) && (k != j)) {
                            t3 = input[k];
                            for(int r=0; r<4; ++r) {
                                if((r!=i) && (r !=j) &&(r !=k)) {
                                    t4 = input[r];
                                    std::array<float, 4> tmp({t1, t2, t3, t4});
                                    data.insert(tmp);
                                }
                            }
                        }
                    }   
                }
            }
        }
    }

public:
    Cal24():a(0), b(0), c(0), d(0), num(0), data(){}
    ~Cal24() 
    {
        num = 0;
        data.swap(std::set<std::array<float, 4>>());
        //data.clear();
    }
    void get_numbers(const float &x, const float &y, const float &z, const float &w) 
    {
        a = x;
        b = y;
        c = z;
        d = w;
        init_set();
    }
    void execute()
    {
        for(auto i = data.begin(); i != data.end(); ++i) {
            float x = (*i)[0];
            float y = (*i)[1];
            float w = (*i)[2];
            float z = (*i)[3];
            cal24(x, y, w, z);
        }
        printf("input numbers are %.0f, %.0f, %.0f, %.0f\n", a, b, c, d);
        printf("There are %d calculation methods", num);
    }
};

#endif

main.cpp

#include <iostream>
#include "cal24.hpp"

int main()
{
	float a, b, c, d;
	std::cout<<"input number 1:";
	std::cin >>a;
	std::cout<<"input number 2:";
	std::cin >>b;
	std::cout<<"input number 3:";
	std::cin >>c;
	std::cout<<"input number 4:";
	std::cin >>d;
    Cal24 e;
    e.get_numbers(a,b,c,d);
    e.execute();
    return 0;
}

CMakeLists.txt

project(test)
cmake_minimum_required(VERSION 3.24)

aux_source_directory(cal24 APP_SRC)
include_directories(cal24)

add_executable(${PROJECT_NAME} main.c ${APP_SRC})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值